mirror of
https://github.com/g4klx/MMDVM.git
synced 2026-10-15 16:24:11 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
40e463591a | ||
|
|
6ef27c27b1 | ||
|
|
72b300efcf | ||
|
|
6694535dec | ||
|
|
5690d4326c | ||
|
|
bd4c0c087c | ||
|
|
5e4e37f8e5 | ||
|
|
0833dba9bd | ||
|
|
047229d6d3 | ||
|
|
d9aec14b7c | ||
|
|
bfd7e8e88f | ||
|
|
404fe52b30 | ||
|
|
4655e33575 | ||
|
|
8d59210846 | ||
|
|
7fee373137 | ||
|
|
d23249dad9 | ||
|
|
6886ebd86d | ||
|
|
478b0fdb32 | ||
|
|
d6e1fadb16 | ||
|
|
7fb3175617 | ||
|
|
9f9abe496d | ||
|
|
e1e9b2682f | ||
|
|
2e9155e0f6 | ||
|
|
9eb11f7434 | ||
|
|
694b83123a | ||
|
|
62f3e01aa5 | ||
|
|
68daa55a79 | ||
|
|
d4c1378ec9 | ||
|
|
af8e9f2659 | ||
|
|
d0d131b0e8 | ||
|
|
226bdf52e1 | ||
|
|
b0ebe60589 | ||
|
|
e760b7c30b | ||
|
|
d532ad63b7 | ||
|
|
37080d9901 |
+7
-7
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2009-2015 by Jonathan Naylor G4KLX
|
* Copyright (C) 2009-2017 by Jonathan Naylor G4KLX
|
||||||
* Copyright (C) 2016 by Colin Durbridge G4EML
|
* Copyright (C) 2016 by Colin Durbridge G4EML
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@@ -17,19 +17,17 @@
|
|||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// #define WANT_DEBUG
|
|
||||||
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "CWIdTX.h"
|
#include "CWIdTX.h"
|
||||||
|
|
||||||
q15_t TONE[] = {
|
q15_t TONE[] = {
|
||||||
0, 518, 1000, 1414, 1732, 1932, 2000, 1932, 1732, 1414, 1000, 518, 0, -518, -1000, -1414, -1732, -1932, -2000, -1932, -1732, -1414, -1000, -518};
|
0, 261, 518, 765, 1000, 1218, 1414, 1587, 1732, 1848, 1932, 1983, 2000, 1983, 1932, 1848, 1732, 1587, 1414, 1218, 1000, 765, 518, 261, 0, -261, -518, -765, -1000, -1218, -1414,
|
||||||
|
-1587, -1732, -1848, -1932, -1983, -2000, -1983, -1932, -1848, -1732, -1587, -1414, -1218, -1000, -765, -518, -261};
|
||||||
q15_t SILENCE[] = {
|
q15_t SILENCE[] = {
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
const uint8_t CYCLE_LENGTH = 24U;
|
const uint8_t CYCLE_LENGTH = 48U;
|
||||||
|
|
||||||
const uint8_t DOT_LENGTH = 50U;
|
const uint8_t DOT_LENGTH = 50U;
|
||||||
|
|
||||||
@@ -77,6 +75,8 @@ const struct {
|
|||||||
{'/', 0xEAE80000U, 16U},
|
{'/', 0xEAE80000U, 16U},
|
||||||
{'?', 0xAEEA0000U, 18U},
|
{'?', 0xAEEA0000U, 18U},
|
||||||
{',', 0xEEAEE000U, 22U},
|
{',', 0xEEAEE000U, 22U},
|
||||||
|
{'-', 0xEAAE0000U, 18U},
|
||||||
|
{'=', 0xEAB80000U, 16U},
|
||||||
{' ', 0x00000000U, 4U},
|
{' ', 0x00000000U, 4U},
|
||||||
{0U, 0x00000000U, 0U}
|
{0U, 0x00000000U, 0U}
|
||||||
};
|
};
|
||||||
|
|||||||
+180
-6
@@ -21,19 +21,190 @@
|
|||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "CalDMR.h"
|
#include "CalDMR.h"
|
||||||
|
|
||||||
|
// Voice LC BS Header, CC: 1, srcID: 1, dstID: TG9
|
||||||
|
const uint8_t VH_1K[] = {0x00U,
|
||||||
|
0x00U, 0x20U, 0x08U, 0x08U, 0x02U, 0x38U, 0x15U, 0x00U, 0x2CU, 0xA0U, 0x14U,
|
||||||
|
0x60U, 0x84U, 0x6DU, 0xFFU, 0x57U, 0xD7U, 0x5DU, 0xF5U, 0xDEU, 0x30U, 0x30U,
|
||||||
|
0x01U, 0x10U, 0x01U, 0x40U, 0x03U, 0xC0U, 0x13U, 0xC1U, 0x1EU, 0x80U, 0x6FU};
|
||||||
|
|
||||||
|
// Voice Term BS with LC, CC: 1, srcID: 1, dstID: TG9
|
||||||
|
const uint8_t VT_1K[] = {0x00U,
|
||||||
|
0x00U, 0x4FU, 0x08U, 0xDCU, 0x02U, 0x88U, 0x15U, 0x78U, 0x2CU, 0xD0U, 0x14U,
|
||||||
|
0xC0U, 0x84U, 0xADU, 0xFFU, 0x57U, 0xD7U, 0x5DU, 0xF5U, 0xD9U, 0x65U, 0x24U,
|
||||||
|
0x02U, 0x28U, 0x06U, 0x20U, 0x0FU, 0x80U, 0x1BU, 0xC1U, 0x07U, 0x80U, 0x5CU};
|
||||||
|
|
||||||
|
// Voice LC MS Header, CC: 1, srcID: 1, dstID: TG9
|
||||||
|
const uint8_t VH_DMO1K[] = {0x00U,
|
||||||
|
0x00U, 0x20U, 0x08U, 0x08U, 0x02U, 0x38U, 0x15U, 0x00U, 0x2CU, 0xA0U, 0x14U,
|
||||||
|
0x60U, 0x84U, 0x6DU, 0x5DU, 0x7FU, 0x77U, 0xFDU, 0x75U, 0x7EU, 0x30U, 0x30U,
|
||||||
|
0x01U, 0x10U, 0x01U, 0x40U, 0x03U, 0xC0U, 0x13U, 0xC1U, 0x1EU, 0x80U, 0x6FU};
|
||||||
|
|
||||||
|
// Voice Term MS with LC, CC: 1, srcID: 1, dstID: TG9
|
||||||
|
const uint8_t VT_DMO1K[] = {0x00U,
|
||||||
|
0x00U, 0x4FU, 0x08U, 0xDCU, 0x02U, 0x88U, 0x15U, 0x78U, 0x2CU, 0xD0U, 0x14U,
|
||||||
|
0xC0U, 0x84U, 0xADU, 0x5DU, 0x7FU, 0x77U, 0xFDU, 0x75U, 0x79U, 0x65U, 0x24U,
|
||||||
|
0x02U, 0x28U, 0x06U, 0x20U, 0x0FU, 0x80U, 0x1BU, 0xC1U, 0x07U, 0x80U, 0x5CU};
|
||||||
|
|
||||||
|
// Voice coding data + FEC, 1031 Hz Test Pattern
|
||||||
|
const uint8_t VOICE_1K[] = {0x00U,
|
||||||
|
0xCEU, 0xA8U, 0xFEU, 0x83U, 0xACU, 0xC4U, 0x58U, 0x20U, 0x0AU, 0xCEU, 0xA8U,
|
||||||
|
0xFEU, 0x83U, 0xA0U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x0CU, 0xC4U, 0x58U,
|
||||||
|
0x20U, 0x0AU, 0xCEU, 0xA8U, 0xFEU, 0x83U, 0xACU, 0xC4U, 0x58U, 0x20U, 0x0AU};
|
||||||
|
|
||||||
|
// Embedded LC BS: CC: 1, srcID: 1, dstID: TG9
|
||||||
|
const uint8_t SYNCEMB_1K[6][7] = {
|
||||||
|
{0x07U, 0x55U, 0xFDU, 0x7DU, 0xF7U, 0x5FU, 0x70U}, // BS VOICE SYNC (audio seq 0)
|
||||||
|
{0x01U, 0x30U, 0x00U, 0x00U, 0x90U, 0x09U, 0x10U}, // EMB + Embedded LC1 (audio seq 1)
|
||||||
|
{0x01U, 0x70U, 0x00U, 0x90U, 0x00U, 0x07U, 0x40U}, // EMB + Embedded LC2 (audio seq 2)
|
||||||
|
{0x01U, 0x70U, 0x00U, 0x31U, 0x40U, 0x07U, 0x40U}, // EMB + Embedded LC3 (audio seq 3)
|
||||||
|
{0x01U, 0x50U, 0xA1U, 0x71U, 0xD1U, 0x70U, 0x70U}, // EMB + Embedded LC4 (audio seq 4)
|
||||||
|
{0x01U, 0x10U, 0x00U, 0x00U, 0x00U, 0x0EU, 0x20U}}; // EMB (audio seq 5)
|
||||||
|
|
||||||
|
// Embedded LC MS: CC: 1, srcID: 1, dstID: TG9
|
||||||
|
const uint8_t SYNCEMB_DMO1K[6][7] = {
|
||||||
|
{0x07U, 0xF7U, 0xD5U, 0xDDU, 0x57U, 0xDFU, 0xD0U}, // MS VOICE SYNC (audio seq 0)
|
||||||
|
{0x01U, 0x30U, 0x00U, 0x00U, 0x90U, 0x09U, 0x10U}, // EMB + Embedded LC1 (audio seq 1)
|
||||||
|
{0x01U, 0x70U, 0x00U, 0x90U, 0x00U, 0x07U, 0x40U}, // EMB + Embedded LC2 (audio seq 2)
|
||||||
|
{0x01U, 0x70U, 0x00U, 0x31U, 0x40U, 0x07U, 0x40U}, // EMB + Embedded LC3 (audio seq 3)
|
||||||
|
{0x01U, 0x50U, 0xA1U, 0x71U, 0xD1U, 0x70U, 0x70U}, // EMB + Embedded LC4 (audio seq 4)
|
||||||
|
{0x01U, 0x10U, 0x00U, 0x00U, 0x00U, 0x0EU, 0x20U}}; // EMB (audio seq 5)
|
||||||
|
|
||||||
|
// Short LC:
|
||||||
|
// TS1: dstID: 0, ACTIVITY_NONE
|
||||||
|
// TS2: dstID: TG9, ACTIVITY_VOICE
|
||||||
|
const uint8_t SHORTLC_1K[] = {0x33U, 0x3AU, 0xA0U, 0x30U, 0x00U, 0x55U, 0xA6U, 0x5FU, 0x50U};
|
||||||
|
|
||||||
CCalDMR::CCalDMR() :
|
CCalDMR::CCalDMR() :
|
||||||
m_transmit(false)
|
m_transmit(false),
|
||||||
|
m_state(DMRCAL1K_IDLE),
|
||||||
|
m_frame_start(0U),
|
||||||
|
m_dmr1k(),
|
||||||
|
m_audioSeq(0)
|
||||||
{
|
{
|
||||||
|
::memcpy(m_dmr1k, VOICE_1K, DMR_FRAME_LENGTH_BYTES + 1U);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCalDMR::process()
|
void CCalDMR::process()
|
||||||
{
|
{
|
||||||
if (m_transmit) {
|
switch (m_modemState) {
|
||||||
dmrTX.setCal(true);
|
case STATE_DMRCAL:
|
||||||
dmrTX.process();
|
case STATE_LFCAL:
|
||||||
} else {
|
if (m_transmit) {
|
||||||
dmrTX.setCal(false);
|
dmrTX.setCal(true);
|
||||||
|
dmrTX.process();
|
||||||
|
} else {
|
||||||
|
dmrTX.setCal(false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case STATE_DMRCAL1K:
|
||||||
|
dmr1kcal();
|
||||||
|
break;
|
||||||
|
case STATE_DMRDMO1K:
|
||||||
|
dmrdmo1k();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCalDMR::createData1k(uint8_t n)
|
||||||
|
{
|
||||||
|
for(uint8_t i = 0; i < 5U; i++)
|
||||||
|
m_dmr1k[i + 15U] = SYNCEMB_1K[n][i + 1U];
|
||||||
|
|
||||||
|
m_dmr1k[14U] &= 0xF0U;
|
||||||
|
m_dmr1k[20U] &= 0x0FU;
|
||||||
|
m_dmr1k[14U] |= SYNCEMB_1K[n][0] & 0x0FU;
|
||||||
|
m_dmr1k[20U] |= SYNCEMB_1K[n][6] & 0xF0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCalDMR::createDataDMO1k(uint8_t n)
|
||||||
|
{
|
||||||
|
for(uint8_t i = 0; i < 5U; i++)
|
||||||
|
m_dmr1k[i + 15U] = SYNCEMB_DMO1K[n][i + 1U];
|
||||||
|
|
||||||
|
m_dmr1k[14U] &= 0xF0U;
|
||||||
|
m_dmr1k[20U] &= 0x0FU;
|
||||||
|
m_dmr1k[14U] |= SYNCEMB_DMO1K[n][0] & 0x0FU;
|
||||||
|
m_dmr1k[20U] |= SYNCEMB_DMO1K[n][6] & 0xF0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCalDMR::dmr1kcal()
|
||||||
|
{
|
||||||
|
dmrTX.process();
|
||||||
|
|
||||||
|
uint16_t space = dmrTX.getSpace2();
|
||||||
|
if (space < 1U)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (m_state) {
|
||||||
|
case DMRCAL1K_VH:
|
||||||
|
dmrTX.setColorCode(1U);
|
||||||
|
dmrTX.writeShortLC(SHORTLC_1K, 9U);
|
||||||
|
dmrTX.writeData2(VH_1K, DMR_FRAME_LENGTH_BYTES + 1U);
|
||||||
|
dmrTX.setStart(true);
|
||||||
|
m_state = DMRCAL1K_VOICE;
|
||||||
|
break;
|
||||||
|
case DMRCAL1K_VOICE:
|
||||||
|
createData1k(m_audioSeq);
|
||||||
|
dmrTX.writeData2(m_dmr1k, DMR_FRAME_LENGTH_BYTES + 1U);
|
||||||
|
if(m_audioSeq == 5U) {
|
||||||
|
m_audioSeq = 0U;
|
||||||
|
if(!m_transmit)
|
||||||
|
m_state = DMRCAL1K_VT;
|
||||||
|
} else
|
||||||
|
m_audioSeq++;
|
||||||
|
break;
|
||||||
|
case DMRCAL1K_VT:
|
||||||
|
dmrTX.writeData2(VT_1K, DMR_FRAME_LENGTH_BYTES + 1U);
|
||||||
|
m_frame_start = dmrTX.getFrameCount();
|
||||||
|
m_state = DMRCAL1K_WAIT;
|
||||||
|
break;
|
||||||
|
case DMRCAL1K_WAIT:
|
||||||
|
if (dmrTX.getFrameCount() > (m_frame_start + 30U)) {
|
||||||
|
dmrTX.setStart(false);
|
||||||
|
dmrTX.resetFifo2();
|
||||||
|
m_audioSeq = 0U;
|
||||||
|
m_state = DMRCAL1K_IDLE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
m_state = DMRCAL1K_IDLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCalDMR::dmrdmo1k()
|
||||||
|
{
|
||||||
|
dmrDMOTX.process();
|
||||||
|
|
||||||
|
uint16_t space = dmrDMOTX.getSpace();
|
||||||
|
if (space < 1U)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (m_state) {
|
||||||
|
case DMRCAL1K_VH:
|
||||||
|
dmrDMOTX.writeData(VH_DMO1K, DMR_FRAME_LENGTH_BYTES + 1U);
|
||||||
|
m_state = DMRCAL1K_VOICE;
|
||||||
|
break;
|
||||||
|
case DMRCAL1K_VOICE:
|
||||||
|
createDataDMO1k(m_audioSeq);
|
||||||
|
dmrDMOTX.writeData(m_dmr1k, DMR_FRAME_LENGTH_BYTES + 1U);
|
||||||
|
if(m_audioSeq == 5U) {
|
||||||
|
m_audioSeq = 0U;
|
||||||
|
if(!m_transmit)
|
||||||
|
m_state = DMRCAL1K_VT;
|
||||||
|
} else
|
||||||
|
m_audioSeq++;
|
||||||
|
break;
|
||||||
|
case DMRCAL1K_VT:
|
||||||
|
dmrDMOTX.writeData(VT_DMO1K, DMR_FRAME_LENGTH_BYTES + 1U);
|
||||||
|
m_state = DMRCAL1K_IDLE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
m_state = DMRCAL1K_IDLE;
|
||||||
|
m_audioSeq = 0U;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,6 +215,9 @@ uint8_t CCalDMR::write(const uint8_t* data, uint8_t length)
|
|||||||
|
|
||||||
m_transmit = data[0U] == 1U;
|
m_transmit = data[0U] == 1U;
|
||||||
|
|
||||||
|
if(m_transmit && m_state == DMRCAL1K_IDLE && (m_modemState == STATE_DMRCAL1K || m_modemState == STATE_DMRDMO1K))
|
||||||
|
m_state = DMRCAL1K_VH;
|
||||||
|
|
||||||
return 0U;
|
return 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,16 +23,32 @@
|
|||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "DMRDefines.h"
|
#include "DMRDefines.h"
|
||||||
|
|
||||||
|
enum DMRCAL1K {
|
||||||
|
DMRCAL1K_IDLE,
|
||||||
|
DMRCAL1K_VH,
|
||||||
|
DMRCAL1K_VOICE,
|
||||||
|
DMRCAL1K_VT,
|
||||||
|
DMRCAL1K_WAIT
|
||||||
|
};
|
||||||
|
|
||||||
class CCalDMR {
|
class CCalDMR {
|
||||||
public:
|
public:
|
||||||
CCalDMR();
|
CCalDMR();
|
||||||
|
|
||||||
void process();
|
void process();
|
||||||
|
void dmr1kcal();
|
||||||
|
void dmrdmo1k();
|
||||||
|
void createData1k(uint8_t n);
|
||||||
|
void createDataDMO1k(uint8_t n);
|
||||||
|
|
||||||
uint8_t write(const uint8_t* data, uint8_t length);
|
uint8_t write(const uint8_t* data, uint8_t length);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_transmit;
|
bool m_transmit;
|
||||||
|
DMRCAL1K m_state;
|
||||||
|
uint32_t m_frame_start;
|
||||||
|
uint8_t m_dmr1k[DMR_FRAME_LENGTH_BYTES + 1U];
|
||||||
|
uint8_t m_audioSeq;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+1
-1
@@ -24,7 +24,7 @@
|
|||||||
const unsigned int BUFFER_LENGTH = 200U;
|
const unsigned int BUFFER_LENGTH = 200U;
|
||||||
|
|
||||||
const uint32_t PLLMAX = 0x10000U;
|
const uint32_t PLLMAX = 0x10000U;
|
||||||
const uint32_t PLLINC = PLLMAX / DSTAR_RADIO_BIT_LENGTH;
|
const uint32_t PLLINC = PLLMAX / DSTAR_RADIO_SYMBOL_LENGTH;
|
||||||
const uint32_t INC = PLLINC / 32U;
|
const uint32_t INC = PLLINC / 32U;
|
||||||
|
|
||||||
// D-Star bit order version of 0x55 0x2D 0x16
|
// D-Star bit order version of 0x55 0x2D 0x16
|
||||||
|
|||||||
+94
@@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 by Andy Uribe CA6JAU
|
||||||
|
*
|
||||||
|
* 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
#include "Globals.h"
|
||||||
|
#include "CalNXDN.h"
|
||||||
|
|
||||||
|
// NXDN 1031 Hz Test Pattern, RAN: 1, Unit ID: 1, Dst Group ID: 1, Outbound Direction
|
||||||
|
const uint8_t NXDN_CAL1K[4][49] = {
|
||||||
|
{0x00U,
|
||||||
|
0xCDU, 0xF5U, 0x9DU, 0x5DU, 0x7CU, 0xFAU, 0x0AU, 0x6EU, 0x8AU, 0x23U, 0x56U, 0xE8U,
|
||||||
|
0x4CU, 0xAAU, 0xDEU, 0x8BU, 0x26U, 0xE4U, 0xF2U, 0x82U, 0x88U,
|
||||||
|
0xC6U, 0x8AU, 0x74U, 0x29U, 0xA4U, 0xECU, 0xD0U, 0x08U, 0x22U,
|
||||||
|
0xCEU, 0xA2U, 0xFCU, 0x01U, 0x8CU, 0xECU, 0xDAU, 0x0AU, 0xA0U,
|
||||||
|
0xEEU, 0x8AU, 0x7EU, 0x2BU, 0x26U, 0xCCU, 0xF8U, 0x8AU, 0x08U},
|
||||||
|
|
||||||
|
{0x00U,
|
||||||
|
0xCDU, 0xF5U, 0x9DU, 0x5DU, 0x7CU, 0x6DU, 0xBBU, 0x0EU, 0xB3U, 0xA4U, 0x26U, 0xA8U,
|
||||||
|
0x4CU, 0xAAU, 0xDEU, 0x8BU, 0x26U, 0xE4U, 0xF2U, 0x82U, 0x88U,
|
||||||
|
0xC6U, 0x8AU, 0x74U, 0x29U, 0xA4U, 0xECU, 0xD0U, 0x08U, 0x22U,
|
||||||
|
0xCEU, 0xA2U, 0xFCU, 0x01U, 0x8CU, 0xECU, 0xDAU, 0x0AU, 0xA0U,
|
||||||
|
0xEEU, 0x8AU, 0x7EU, 0x2BU, 0x26U, 0xCCU, 0xF8U, 0x8AU, 0x08U},
|
||||||
|
|
||||||
|
{0x00U,
|
||||||
|
0xCDU, 0xF5U, 0x9DU, 0x5DU, 0x76U, 0x3AU, 0x1BU, 0x4AU, 0x81U, 0xA8U, 0xE2U, 0x80U,
|
||||||
|
0x4CU, 0xAAU, 0xDEU, 0x8BU, 0x26U, 0xE4U, 0xF2U, 0x82U, 0x88U,
|
||||||
|
0xC6U, 0x8AU, 0x74U, 0x29U, 0xA4U, 0xECU, 0xD0U, 0x08U, 0x22U,
|
||||||
|
0xCEU, 0xA2U, 0xFCU, 0x01U, 0x8CU, 0xECU, 0xDAU, 0x0AU, 0xA0U,
|
||||||
|
0xEEU, 0x8AU, 0x7EU, 0x2BU, 0x26U, 0xCCU, 0xF8U, 0x8AU, 0x08U},
|
||||||
|
|
||||||
|
{0x00U,
|
||||||
|
0xCDU, 0xF5U, 0x9DU, 0x5DU, 0x74U, 0x28U, 0x83U, 0x02U, 0xB0U, 0x2DU, 0x07U, 0xE2U,
|
||||||
|
0x4CU, 0xAAU, 0xDEU, 0x8BU, 0x26U, 0xE4U, 0xF2U, 0x82U, 0x88U,
|
||||||
|
0xC6U, 0x8AU, 0x74U, 0x29U, 0xA4U, 0xECU, 0xD0U, 0x08U, 0x22U,
|
||||||
|
0xCEU, 0xA2U, 0xFCU, 0x01U, 0x8CU, 0xECU, 0xDAU, 0x0AU, 0xA0U,
|
||||||
|
0xEEU, 0x8AU, 0x7EU, 0x2BU, 0x26U, 0xCCU, 0xF8U, 0x8AU, 0x08U}};
|
||||||
|
|
||||||
|
CCalNXDN::CCalNXDN() :
|
||||||
|
m_transmit(false),
|
||||||
|
m_state(NXDNCAL1K_IDLE),
|
||||||
|
m_audioSeq(0U)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCalNXDN::process()
|
||||||
|
{
|
||||||
|
nxdnTX.process();
|
||||||
|
|
||||||
|
uint16_t space = nxdnTX.getSpace();
|
||||||
|
if (space < 1U)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (m_state) {
|
||||||
|
case NXDNCAL1K_TX:
|
||||||
|
nxdnTX.writeData(NXDN_CAL1K[m_audioSeq], NXDN_FRAME_LENGTH_BYTES + 1U);
|
||||||
|
m_audioSeq = (m_audioSeq + 1U) % 4U;
|
||||||
|
if(!m_transmit)
|
||||||
|
m_state = NXDNCAL1K_IDLE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
m_state = NXDNCAL1K_IDLE;
|
||||||
|
m_audioSeq = 0U;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t CCalNXDN::write(const uint8_t* data, uint8_t length)
|
||||||
|
{
|
||||||
|
if (length != 1U)
|
||||||
|
return 4U;
|
||||||
|
|
||||||
|
m_transmit = data[0U] == 1U;
|
||||||
|
|
||||||
|
if(m_transmit && m_state == NXDNCAL1K_IDLE)
|
||||||
|
m_state = NXDNCAL1K_TX;
|
||||||
|
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 by Andy Uribe CA6JAU
|
||||||
|
*
|
||||||
|
* 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(CALNXDN_H)
|
||||||
|
#define CALNXDN_H
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
|
enum NXDNCAL1K {
|
||||||
|
NXDNCAL1K_IDLE,
|
||||||
|
NXDNCAL1K_TX
|
||||||
|
};
|
||||||
|
|
||||||
|
class CCalNXDN {
|
||||||
|
public:
|
||||||
|
CCalNXDN();
|
||||||
|
|
||||||
|
void process();
|
||||||
|
|
||||||
|
uint8_t write(const uint8_t* data, uint8_t length);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_transmit;
|
||||||
|
NXDNCAL1K m_state;
|
||||||
|
uint8_t m_audioSeq;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
+97
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 by Andy Uribe CA6JAU
|
||||||
|
*
|
||||||
|
* 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
#include "Globals.h"
|
||||||
|
#include "CalP25.h"
|
||||||
|
|
||||||
|
// Recommended 1011 Hz test pattern for P25 Phase 1 (ANSI/TIA-102.CAAA)
|
||||||
|
// NAC: 0x293, srcID: 1, dstID: TG1
|
||||||
|
unsigned char LDU1_1K[] = {0x00,
|
||||||
|
0x55, 0x75, 0xF5, 0xFF, 0x77, 0xFF, 0x29, 0x35, 0x54, 0x7B, 0xCB, 0x19, 0x4D, 0x0D, 0xCE, 0x24, 0xA1, 0x24,
|
||||||
|
0x0D, 0x43, 0x3C, 0x0B, 0xE1, 0xB9, 0x18, 0x44, 0xFC, 0xC1, 0x62, 0x96, 0x27, 0x60, 0xE4, 0xE2, 0x4A, 0x10,
|
||||||
|
0x90, 0xD4, 0x33, 0xC0, 0xBE, 0x1B, 0x91, 0x84, 0x4C, 0xFC, 0x16, 0x29, 0x62, 0x76, 0x0E, 0xC0, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x03, 0x89, 0x28, 0x49, 0x0D, 0x43, 0x3C, 0x02, 0xF8, 0x6E, 0x46, 0x11, 0x3F, 0xC1, 0x62, 0x94,
|
||||||
|
0x89, 0xD8, 0x39, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x38, 0x24, 0xA1, 0x24, 0x35, 0x0C, 0xF0, 0x2F, 0x86, 0xE4,
|
||||||
|
0x18, 0x44, 0xFF, 0x05, 0x8A, 0x58, 0x9D, 0x83, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x70, 0xE2, 0x4A, 0x12, 0x40,
|
||||||
|
0xD4, 0x33, 0xC0, 0xBE, 0x1B, 0x91, 0x84, 0x4F, 0xF0, 0x16, 0x29, 0x62, 0x76, 0x0E, 0x6D, 0xE5, 0xD5, 0x48,
|
||||||
|
0xAD, 0xE3, 0x89, 0x28, 0x49, 0x0D, 0x43, 0x3C, 0x08, 0xF8, 0x6E, 0x46, 0x11, 0x3F, 0xC1, 0x62, 0x96, 0x24,
|
||||||
|
0xD8, 0x3B, 0xA1, 0x41, 0xC2, 0xD2, 0xBA, 0x38, 0x90, 0xA1, 0x24, 0x35, 0x0C, 0xF0, 0x2F, 0x86, 0xE4, 0x60,
|
||||||
|
0x44, 0xFF, 0x05, 0x8A, 0x58, 0x9D, 0x83, 0x94, 0xC8, 0xFB, 0x02, 0x35, 0xA4, 0xE2, 0x4A, 0x12, 0x43, 0x50,
|
||||||
|
0x33, 0xC0, 0xBE, 0x1B, 0x91, 0x84, 0x4F, 0xF0, 0x58, 0x29, 0x62, 0x76, 0x0E, 0xC0, 0x00, 0x00, 0x00, 0x0C,
|
||||||
|
0x89, 0x28, 0x49, 0x0D, 0x43, 0x3C, 0x0B, 0xE1, 0xB8, 0x46, 0x11, 0x3F, 0xC1, 0x62, 0x96, 0x27, 0x60, 0xE4};
|
||||||
|
|
||||||
|
unsigned char LDU2_1K[] = {0x00,
|
||||||
|
0x55, 0x75, 0xF5, 0xFF, 0x77, 0xFF, 0x29, 0x3A, 0xB8, 0xA4, 0xEF, 0xB0, 0x9A, 0x8A, 0xCE, 0x24, 0xA1, 0x24,
|
||||||
|
0x0D, 0x43, 0x3C, 0x0B, 0xE1, 0xB9, 0x18, 0x44, 0xFC, 0xC1, 0x62, 0x96, 0x27, 0x60, 0xEC, 0xE2, 0x4A, 0x10,
|
||||||
|
0x90, 0xD4, 0x33, 0xC0, 0xBE, 0x1B, 0x91, 0x84, 0x4C, 0xFC, 0x16, 0x29, 0x62, 0x76, 0x0E, 0x40, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x03, 0x89, 0x28, 0x49, 0x0D, 0x43, 0x3C, 0x02, 0xF8, 0x6E, 0x46, 0x11, 0x3F, 0xC1, 0x62, 0x94,
|
||||||
|
0x89, 0xD8, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x24, 0xA1, 0x24, 0x35, 0x0C, 0xF0, 0x2F, 0x86, 0xE4,
|
||||||
|
0x18, 0x44, 0xFF, 0x05, 0x8A, 0x58, 0x9D, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE2, 0x4A, 0x12, 0x40,
|
||||||
|
0xD4, 0x33, 0xC0, 0xBE, 0x1B, 0x91, 0x84, 0x4F, 0xF0, 0x16, 0x29, 0x62, 0x76, 0x0E, 0xE0, 0xE0, 0x00, 0x00,
|
||||||
|
0x00, 0x03, 0x89, 0x28, 0x49, 0x0D, 0x43, 0x3C, 0x08, 0xF8, 0x6E, 0x46, 0x11, 0x3F, 0xC1, 0x62, 0x96, 0x24,
|
||||||
|
0xD8, 0x39, 0xAE, 0x8B, 0x48, 0xB6, 0x49, 0x38, 0x90, 0xA1, 0x24, 0x35, 0x0C, 0xF0, 0x2F, 0x86, 0xE4, 0x60,
|
||||||
|
0x44, 0xFF, 0x05, 0x8A, 0x58, 0x9D, 0x83, 0xB9, 0xA8, 0xF4, 0xF1, 0xFD, 0x60, 0xE2, 0x4A, 0x12, 0x43, 0x50,
|
||||||
|
0x33, 0xC0, 0xBE, 0x1B, 0x91, 0x84, 0x4F, 0xF0, 0x58, 0x29, 0x62, 0x76, 0x0E, 0x40, 0x00, 0x00, 0x00, 0x0C,
|
||||||
|
0x89, 0x28, 0x49, 0x0D, 0x43, 0x3C, 0x0B, 0xE1, 0xB8, 0x46, 0x11, 0x3F, 0xC1, 0x62, 0x96, 0x27, 0x60, 0xEC};
|
||||||
|
|
||||||
|
CCalP25::CCalP25() :
|
||||||
|
m_transmit(false),
|
||||||
|
m_state(P25CAL1K_IDLE)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCalP25::process()
|
||||||
|
{
|
||||||
|
p25TX.process();
|
||||||
|
|
||||||
|
uint16_t space = p25TX.getSpace();
|
||||||
|
if (space < 1U)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (m_state) {
|
||||||
|
case P25CAL1K_LDU1:
|
||||||
|
p25TX.writeData(LDU1_1K, P25_LDU_FRAME_LENGTH_BYTES + 1U);
|
||||||
|
m_state = P25CAL1K_LDU2;
|
||||||
|
break;
|
||||||
|
case P25CAL1K_LDU2:
|
||||||
|
p25TX.writeData(LDU2_1K, P25_LDU_FRAME_LENGTH_BYTES + 1U);
|
||||||
|
if(!m_transmit)
|
||||||
|
m_state = P25CAL1K_IDLE;
|
||||||
|
else
|
||||||
|
m_state = P25CAL1K_LDU1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
m_state = P25CAL1K_IDLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t CCalP25::write(const uint8_t* data, uint8_t length)
|
||||||
|
{
|
||||||
|
if (length != 1U)
|
||||||
|
return 4U;
|
||||||
|
|
||||||
|
m_transmit = data[0U] == 1U;
|
||||||
|
|
||||||
|
if(m_transmit && m_state == P25CAL1K_IDLE)
|
||||||
|
m_state = P25CAL1K_LDU1;
|
||||||
|
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 by Andy Uribe CA6JAU
|
||||||
|
*
|
||||||
|
* 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(CALP25_H)
|
||||||
|
#define CALP25_H
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
#include "P25Defines.h"
|
||||||
|
|
||||||
|
enum P25CAL1K {
|
||||||
|
P25CAL1K_IDLE,
|
||||||
|
P25CAL1K_LDU1,
|
||||||
|
P25CAL1K_LDU2
|
||||||
|
};
|
||||||
|
|
||||||
|
class CCalP25 {
|
||||||
|
public:
|
||||||
|
CCalP25();
|
||||||
|
|
||||||
|
void process();
|
||||||
|
|
||||||
|
uint8_t write(const uint8_t* data, uint8_t length);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_transmit;
|
||||||
|
P25CAL1K m_state;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
+65
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 by Jonathan Naylor G4KLX
|
||||||
|
*
|
||||||
|
* 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
#include "Globals.h"
|
||||||
|
#include "CalRSSI.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
CCalRSSI::CCalRSSI() :
|
||||||
|
m_count(0U),
|
||||||
|
m_accum(0U),
|
||||||
|
m_min(0xFFFFU),
|
||||||
|
m_max(0x0000U)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCalRSSI::samples(const uint16_t* rssi, uint8_t length)
|
||||||
|
{
|
||||||
|
for (uint16_t i = 0U; i < length; i++) {
|
||||||
|
uint16_t ss = rssi[i];
|
||||||
|
|
||||||
|
m_accum += ss;
|
||||||
|
|
||||||
|
if (ss > m_max)
|
||||||
|
m_max = ss;
|
||||||
|
if (ss < m_min)
|
||||||
|
m_min = ss;
|
||||||
|
|
||||||
|
m_count++;
|
||||||
|
if (m_count >= 24000U) {
|
||||||
|
uint16_t ave = m_accum / m_count;
|
||||||
|
|
||||||
|
uint8_t buffer[6U];
|
||||||
|
buffer[0U] = (m_max >> 8) & 0xFFU;
|
||||||
|
buffer[1U] = (m_max >> 0) & 0xFFU;
|
||||||
|
buffer[2U] = (m_min >> 8) & 0xFFU;
|
||||||
|
buffer[3U] = (m_min >> 0) & 0xFFU;
|
||||||
|
buffer[4U] = (ave >> 8) & 0xFFU;
|
||||||
|
buffer[5U] = (ave >> 0) & 0xFFU;
|
||||||
|
|
||||||
|
serial.writeRSSIData(buffer, 6U);
|
||||||
|
|
||||||
|
m_count = 0U;
|
||||||
|
m_accum = 0U;
|
||||||
|
m_min = 0xFFFFU;
|
||||||
|
m_max = 0x0000U;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 by Jonathan Naylor G4KLX
|
||||||
|
*
|
||||||
|
* 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(CALRSSI_H)
|
||||||
|
#define CALRSSI_H
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
|
class CCalRSSI {
|
||||||
|
public:
|
||||||
|
CCalRSSI();
|
||||||
|
|
||||||
|
void samples(const uint16_t* rssi, uint8_t length);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_count;
|
||||||
|
uint32_t m_accum;
|
||||||
|
uint16_t m_min;
|
||||||
|
uint16_t m_max;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
// Frequencies such as 10.0 Mhz (48000 * 208.333) or 20 Mhz (48000 * 416.666) are not suitable.
|
// Frequencies such as 10.0 Mhz (48000 * 208.333) or 20 Mhz (48000 * 416.666) are not suitable.
|
||||||
//
|
//
|
||||||
// For 12 MHz
|
// For 12 MHz
|
||||||
// #define EXTERNAL_OSC 12000000
|
#define EXTERNAL_OSC 12000000
|
||||||
// For 12.288 MHz
|
// For 12.288 MHz
|
||||||
// #define EXTERNAL_OSC 12288000
|
// #define EXTERNAL_OSC 12288000
|
||||||
// For 14.4 MHz
|
// For 14.4 MHz
|
||||||
@@ -38,28 +38,51 @@
|
|||||||
// Allow the use of the COS line to lockout the modem
|
// Allow the use of the COS line to lockout the modem
|
||||||
// #define USE_COS_AS_LOCKOUT
|
// #define USE_COS_AS_LOCKOUT
|
||||||
|
|
||||||
// Use pins to output the current mode
|
// Use pins to output the current mode via LEDs
|
||||||
// #define ARDUINO_MODE_PINS
|
// #define MODE_LEDS
|
||||||
|
|
||||||
// For the original Arduino Due pin layout
|
// For the original Arduino Due pin layout
|
||||||
// #define ARDUINO_DUE_PAPA
|
// #define ARDUINO_DUE_PAPA
|
||||||
|
|
||||||
// For the ZUM V1.0 and V1.0.1 boards pin layout
|
// For the ZUM V1.0 and V1.0.1 boards pin layout
|
||||||
#define ARDUINO_DUE_ZUM_V10
|
// #define ARDUINO_DUE_ZUM_V10
|
||||||
|
|
||||||
|
// For the SQ6POG board
|
||||||
|
// #define STM32F1_POG
|
||||||
|
|
||||||
// For the SP8NTH board
|
// For the SP8NTH board
|
||||||
// #define ARDUINO_DUE_NTH
|
// #define ARDUINO_DUE_NTH
|
||||||
|
|
||||||
// To use wider C4FSK filters for DMR, System Fusion and P25 on transmit
|
// For ST Nucleo-64 STM32F446RE board
|
||||||
// #define WIDE_C4FSK_FILTERS_TX
|
// #define STM32F4_NUCLEO_MORPHO_HEADER
|
||||||
// To use wider C4FSK filters for DMR, System Fusion and P25 on receive
|
#define STM32F4_NUCLEO_ARDUINO_HEADER
|
||||||
// #define WIDE_C4FSK_FILTERS_RX
|
|
||||||
|
// Use separate mode pins to switch external channel/filters/bandwidth for example
|
||||||
|
// #define MODE_PINS
|
||||||
|
|
||||||
|
// For the VK6MST Pi3 Shield communicating over i2c. i2c address & speed defined in i2cTeensy.cpp
|
||||||
|
// #define VK6MST_TEENSY_PI3_SHIELD_I2C
|
||||||
|
|
||||||
// Pass RSSI information to the host
|
// Pass RSSI information to the host
|
||||||
// #define SEND_RSSI_DATA
|
#define SEND_RSSI_DATA
|
||||||
|
|
||||||
// Use the modem as a serial repeater for Nextion displays
|
// Use the modem as a serial repeater for Nextion displays
|
||||||
// #define SERIAL_REPEATER
|
// #define SERIAL_REPEATER
|
||||||
|
|
||||||
#endif
|
// To reduce CPU load, you can remove the DC blocker by commenting out the next line
|
||||||
|
// #define USE_DCBLOCKER
|
||||||
|
|
||||||
|
// Constant Service LED once repeater is running
|
||||||
|
// Do not use if employing an external hardware watchdog
|
||||||
|
// #define CONSTANT_SRV_LED
|
||||||
|
|
||||||
|
// Use the YSF and P25 LEDs for NXDN
|
||||||
|
// #define USE_ALTERNATE_NXDN_LEDS
|
||||||
|
|
||||||
|
// Use the D-Star and DMR LEDs for POCSAG
|
||||||
|
// #define USE_ALTERNATE_POCSAG_LEDS
|
||||||
|
|
||||||
|
// Select BOXCAR Filter into D-Star
|
||||||
|
// #define DSTARBOXCAR
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
+70
-83
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2009-2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2009-2017 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -16,8 +16,6 @@
|
|||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define WANT_DEBUG
|
|
||||||
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "DMRDMORX.h"
|
#include "DMRDMORX.h"
|
||||||
@@ -59,8 +57,7 @@ m_colorCode(0U),
|
|||||||
m_state(DMORXS_NONE),
|
m_state(DMORXS_NONE),
|
||||||
m_n(0U),
|
m_n(0U),
|
||||||
m_type(0U),
|
m_type(0U),
|
||||||
m_rssiCount(0U),
|
m_rssi()
|
||||||
m_rssi(0U)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +70,6 @@ void CDMRDMORX::reset()
|
|||||||
m_state = DMORXS_NONE;
|
m_state = DMORXS_NONE;
|
||||||
m_startPtr = 0U;
|
m_startPtr = 0U;
|
||||||
m_endPtr = NOENDPTR;
|
m_endPtr = NOENDPTR;
|
||||||
m_rssiCount = 0U;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDMRDMORX::samples(const q15_t* samples, const uint16_t* rssi, uint8_t length)
|
void CDMRDMORX::samples(const q15_t* samples, const uint16_t* rssi, uint8_t length)
|
||||||
@@ -89,6 +85,7 @@ void CDMRDMORX::samples(const q15_t* samples, const uint16_t* rssi, uint8_t leng
|
|||||||
bool CDMRDMORX::processSample(q15_t sample, uint16_t rssi)
|
bool CDMRDMORX::processSample(q15_t sample, uint16_t rssi)
|
||||||
{
|
{
|
||||||
m_buffer[m_dataPtr] = sample;
|
m_buffer[m_dataPtr] = sample;
|
||||||
|
m_rssi[m_dataPtr] = rssi;
|
||||||
|
|
||||||
m_bitBuffer[m_bitPtr] <<= 1;
|
m_bitBuffer[m_bitPtr] <<= 1;
|
||||||
if (sample < 0)
|
if (sample < 0)
|
||||||
@@ -97,9 +94,6 @@ bool CDMRDMORX::processSample(q15_t sample, uint16_t rssi)
|
|||||||
if (m_state == DMORXS_NONE) {
|
if (m_state == DMORXS_NONE) {
|
||||||
correlateSync(true);
|
correlateSync(true);
|
||||||
} else {
|
} else {
|
||||||
// Grab the RSSI data during the frame
|
|
||||||
if (m_state == DMORXS_VOICE && m_dataPtr == m_syncPtr)
|
|
||||||
m_rssi = rssi;
|
|
||||||
|
|
||||||
uint16_t min = m_syncPtr + DMO_BUFFER_LENGTH_SAMPLES - 1U;
|
uint16_t min = m_syncPtr + DMO_BUFFER_LENGTH_SAMPLES - 1U;
|
||||||
uint16_t max = m_syncPtr + 1U;
|
uint16_t max = m_syncPtr + 1U;
|
||||||
@@ -148,7 +142,7 @@ bool CDMRDMORX::processSample(q15_t sample, uint16_t rssi)
|
|||||||
switch (dataType) {
|
switch (dataType) {
|
||||||
case DT_DATA_HEADER:
|
case DT_DATA_HEADER:
|
||||||
DEBUG4("DMRDMORX: data header found pos/centre/threshold", m_syncPtr, centre, threshold);
|
DEBUG4("DMRDMORX: data header found pos/centre/threshold", m_syncPtr, centre, threshold);
|
||||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
writeRSSIData(frame);
|
||||||
m_state = DMORXS_DATA;
|
m_state = DMORXS_DATA;
|
||||||
m_type = 0x00U;
|
m_type = 0x00U;
|
||||||
break;
|
break;
|
||||||
@@ -157,32 +151,32 @@ bool CDMRDMORX::processSample(q15_t sample, uint16_t rssi)
|
|||||||
case DT_RATE_1_DATA:
|
case DT_RATE_1_DATA:
|
||||||
if (m_state == DMORXS_DATA) {
|
if (m_state == DMORXS_DATA) {
|
||||||
DEBUG4("DMRDMORX: data payload found pos/centre/threshold", m_syncPtr, centre, threshold);
|
DEBUG4("DMRDMORX: data payload found pos/centre/threshold", m_syncPtr, centre, threshold);
|
||||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
writeRSSIData(frame);
|
||||||
m_type = dataType;
|
m_type = dataType;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DT_VOICE_LC_HEADER:
|
case DT_VOICE_LC_HEADER:
|
||||||
DEBUG4("DMRDMORX: voice header found pos/centre/threshold", m_syncPtr, centre, threshold);
|
DEBUG4("DMRDMORX: voice header found pos/centre/threshold", m_syncPtr, centre, threshold);
|
||||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
writeRSSIData(frame);
|
||||||
m_state = DMORXS_VOICE;
|
m_state = DMORXS_VOICE;
|
||||||
break;
|
break;
|
||||||
case DT_VOICE_PI_HEADER:
|
case DT_VOICE_PI_HEADER:
|
||||||
if (m_state == DMORXS_VOICE) {
|
if (m_state == DMORXS_VOICE) {
|
||||||
DEBUG4("DMRDMORX: voice pi header found pos/centre/threshold", m_syncPtr, centre, threshold);
|
DEBUG4("DMRDMORX: voice pi header found pos/centre/threshold", m_syncPtr, centre, threshold);
|
||||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
writeRSSIData(frame);
|
||||||
}
|
}
|
||||||
m_state = DMORXS_VOICE;
|
m_state = DMORXS_VOICE;
|
||||||
break;
|
break;
|
||||||
case DT_TERMINATOR_WITH_LC:
|
case DT_TERMINATOR_WITH_LC:
|
||||||
if (m_state == DMORXS_VOICE) {
|
if (m_state == DMORXS_VOICE) {
|
||||||
DEBUG4("DMRDMORX: voice terminator found pos/centre/threshold", m_syncPtr, centre, threshold);
|
DEBUG4("DMRDMORX: voice terminator found pos/centre/threshold", m_syncPtr, centre, threshold);
|
||||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
writeRSSIData(frame);
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: // DT_CSBK
|
default: // DT_CSBK
|
||||||
DEBUG4("DMRDMORX: csbk found pos/centre/threshold", m_syncPtr, centre, threshold);
|
DEBUG4("DMRDMORX: csbk found pos/centre/threshold", m_syncPtr, centre, threshold);
|
||||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
writeRSSIData(frame);
|
||||||
reset();
|
reset();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -190,22 +184,7 @@ bool CDMRDMORX::processSample(q15_t sample, uint16_t rssi)
|
|||||||
} else if (m_control == CONTROL_VOICE) {
|
} else if (m_control == CONTROL_VOICE) {
|
||||||
// Voice sync
|
// Voice sync
|
||||||
DEBUG4("DMRDMORX: voice sync found pos/centre/threshold", m_syncPtr, centre, threshold);
|
DEBUG4("DMRDMORX: voice sync found pos/centre/threshold", m_syncPtr, centre, threshold);
|
||||||
#if defined(SEND_RSSI_DATA)
|
writeRSSIData(frame);
|
||||||
// Send RSSI data approximately every second
|
|
||||||
if (m_rssiCount == 2U) {
|
|
||||||
frame[34U] = (m_rssi >> 8) & 0xFFU;
|
|
||||||
frame[35U] = (m_rssi >> 0) & 0xFFU;
|
|
||||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 3U);
|
|
||||||
} else {
|
|
||||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_rssiCount++;
|
|
||||||
if (m_rssiCount >= 16U)
|
|
||||||
m_rssiCount = 0U;
|
|
||||||
#else
|
|
||||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
|
||||||
#endif
|
|
||||||
m_state = DMORXS_VOICE;
|
m_state = DMORXS_VOICE;
|
||||||
m_syncCount = 0U;
|
m_syncCount = 0U;
|
||||||
m_n = 0U;
|
m_n = 0U;
|
||||||
@@ -225,26 +204,12 @@ bool CDMRDMORX::processSample(q15_t sample, uint16_t rssi)
|
|||||||
} else {
|
} else {
|
||||||
frame[0U] = ++m_n;
|
frame[0U] = ++m_n;
|
||||||
}
|
}
|
||||||
#if defined(SEND_RSSI_DATA)
|
|
||||||
// Send RSSI data approximately every second
|
|
||||||
if (m_rssiCount == 2U) {
|
|
||||||
frame[34U] = (m_rssi >> 8) & 0xFFU;
|
|
||||||
frame[35U] = (m_rssi >> 0) & 0xFFU;
|
|
||||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 3U);
|
|
||||||
} else {
|
|
||||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_rssiCount++;
|
|
||||||
if (m_rssiCount >= 16U)
|
|
||||||
m_rssiCount = 0U;
|
|
||||||
#else
|
|
||||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
||||||
#endif
|
|
||||||
} else if (m_state == DMORXS_DATA) {
|
} else if (m_state == DMORXS_DATA) {
|
||||||
if (m_type != 0x00U) {
|
if (m_type != 0x00U) {
|
||||||
frame[0U] = CONTROL_DATA | m_type;
|
frame[0U] = CONTROL_DATA | m_type;
|
||||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
writeRSSIData(frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -267,16 +232,13 @@ bool CDMRDMORX::processSample(q15_t sample, uint16_t rssi)
|
|||||||
|
|
||||||
void CDMRDMORX::correlateSync(bool first)
|
void CDMRDMORX::correlateSync(bool first)
|
||||||
{
|
{
|
||||||
uint8_t errs1 = countBits32((m_bitBuffer[m_bitPtr] & DMR_SYNC_SYMBOLS_MASK) ^ DMR_S2_DATA_SYNC_SYMBOLS);
|
uint8_t errs = countBits32((m_bitBuffer[m_bitPtr] & DMR_SYNC_SYMBOLS_MASK) ^ DMR_MS_DATA_SYNC_SYMBOLS);
|
||||||
uint8_t errs2 = countBits32((m_bitBuffer[m_bitPtr] & DMR_SYNC_SYMBOLS_MASK) ^ DMR_MS_DATA_SYNC_SYMBOLS);
|
|
||||||
|
|
||||||
// The voice sync is the complement of the data sync
|
// The voice sync is the complement of the data sync
|
||||||
bool data1 = (errs1 <= MAX_SYNC_SYMBOLS_ERRS);
|
bool data = (errs <= MAX_SYNC_SYMBOLS_ERRS);
|
||||||
bool data2 = (errs2 <= MAX_SYNC_SYMBOLS_ERRS);
|
bool voice = (errs >= (DMR_SYNC_LENGTH_SYMBOLS - MAX_SYNC_SYMBOLS_ERRS));
|
||||||
bool voice1 = (errs1 >= (DMR_SYNC_LENGTH_SYMBOLS - MAX_SYNC_SYMBOLS_ERRS));
|
|
||||||
bool voice2 = (errs2 >= (DMR_SYNC_LENGTH_SYMBOLS - MAX_SYNC_SYMBOLS_ERRS));
|
|
||||||
|
|
||||||
if (data1 || data2 || voice1 || voice2) {
|
if (data || voice) {
|
||||||
uint16_t ptr = m_dataPtr + DMO_BUFFER_LENGTH_SAMPLES - DMR_SYNC_LENGTH_SAMPLES + DMR_RADIO_SYMBOL_LENGTH;
|
uint16_t ptr = m_dataPtr + DMO_BUFFER_LENGTH_SAMPLES - DMR_SYNC_LENGTH_SAMPLES + DMR_RADIO_SYMBOL_LENGTH;
|
||||||
if (ptr >= DMO_BUFFER_LENGTH_SAMPLES)
|
if (ptr >= DMO_BUFFER_LENGTH_SAMPLES)
|
||||||
ptr -= DMO_BUFFER_LENGTH_SAMPLES;
|
ptr -= DMO_BUFFER_LENGTH_SAMPLES;
|
||||||
@@ -285,23 +247,34 @@ void CDMRDMORX::correlateSync(bool first)
|
|||||||
q15_t min = 16000;
|
q15_t min = 16000;
|
||||||
q15_t max = -16000;
|
q15_t max = -16000;
|
||||||
|
|
||||||
uint32_t mask = 0x00800000U;
|
for (uint8_t i = 0U; i < DMR_SYNC_LENGTH_SYMBOLS; i++) {
|
||||||
for (uint8_t i = 0U; i < DMR_SYNC_LENGTH_SYMBOLS; i++, mask >>= 1) {
|
q15_t val = m_buffer[ptr];
|
||||||
bool b;
|
|
||||||
if (data1 || voice1)
|
if (val > max)
|
||||||
b = (DMR_S2_DATA_SYNC_SYMBOLS & mask) == mask;
|
max = val;
|
||||||
|
if (val < min)
|
||||||
|
min = val;
|
||||||
|
|
||||||
|
int8_t corrVal;
|
||||||
|
if (data)
|
||||||
|
corrVal = DMR_MS_DATA_SYNC_SYMBOLS_VALUES[i];
|
||||||
else
|
else
|
||||||
b = (DMR_MS_DATA_SYNC_SYMBOLS & mask) == mask;
|
corrVal = DMR_MS_VOICE_SYNC_SYMBOLS_VALUES[i];
|
||||||
|
|
||||||
if (m_buffer[ptr] > max)
|
switch (corrVal) {
|
||||||
max = m_buffer[ptr];
|
case +3:
|
||||||
if (m_buffer[ptr] < min)
|
corr -= (val + val + val);
|
||||||
min = m_buffer[ptr];
|
break;
|
||||||
|
case +1:
|
||||||
if (data1 || data2)
|
corr -= val;
|
||||||
corr += b ? -m_buffer[ptr] : m_buffer[ptr];
|
break;
|
||||||
else // if (voice)
|
case -1:
|
||||||
corr += b ? m_buffer[ptr] : -m_buffer[ptr];
|
corr += val;
|
||||||
|
break;
|
||||||
|
default: // -3
|
||||||
|
corr += (val + val + val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
ptr += DMR_RADIO_SYMBOL_LENGTH;
|
ptr += DMR_RADIO_SYMBOL_LENGTH;
|
||||||
if (ptr >= DMO_BUFFER_LENGTH_SAMPLES)
|
if (ptr >= DMO_BUFFER_LENGTH_SAMPLES)
|
||||||
@@ -321,21 +294,16 @@ void CDMRDMORX::correlateSync(bool first)
|
|||||||
|
|
||||||
samplesToBits(ptr, DMR_SYNC_LENGTH_SYMBOLS, sync, 4U, centre, threshold);
|
samplesToBits(ptr, DMR_SYNC_LENGTH_SYMBOLS, sync, 4U, centre, threshold);
|
||||||
|
|
||||||
if (data1 || data2) {
|
if (data) {
|
||||||
uint8_t errs = 0U;
|
uint8_t errs = 0U;
|
||||||
for (uint8_t i = 0U; i < DMR_SYNC_BYTES_LENGTH; i++) {
|
for (uint8_t i = 0U; i < DMR_SYNC_BYTES_LENGTH; i++)
|
||||||
if (data1)
|
errs += countBits8((sync[i] & DMR_SYNC_BYTES_MASK[i]) ^ DMR_MS_DATA_SYNC_BYTES[i]);
|
||||||
errs += countBits8((sync[i] & DMR_SYNC_BYTES_MASK[i]) ^ DMR_S2_DATA_SYNC_BYTES[i]);
|
|
||||||
else
|
|
||||||
errs += countBits8((sync[i] & DMR_SYNC_BYTES_MASK[i]) ^ DMR_MS_DATA_SYNC_BYTES[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errs <= MAX_SYNC_BYTES_ERRS) {
|
if (errs <= MAX_SYNC_BYTES_ERRS) {
|
||||||
if (first) {
|
if (first) {
|
||||||
m_threshold[0U] = m_threshold[1U] = m_threshold[2U] = m_threshold[3U] = threshold;
|
m_threshold[0U] = m_threshold[1U] = m_threshold[2U] = m_threshold[3U] = threshold;
|
||||||
m_centre[0U] = m_centre[1U] = m_centre[2U] = m_centre[3U] = centre;
|
m_centre[0U] = m_centre[1U] = m_centre[2U] = m_centre[3U] = centre;
|
||||||
m_averagePtr = 0U;
|
m_averagePtr = 0U;
|
||||||
m_rssiCount = 0U;
|
|
||||||
} else {
|
} else {
|
||||||
m_threshold[m_averagePtr] = threshold;
|
m_threshold[m_averagePtr] = threshold;
|
||||||
m_centre[m_averagePtr] = centre;
|
m_centre[m_averagePtr] = centre;
|
||||||
@@ -359,19 +327,14 @@ void CDMRDMORX::correlateSync(bool first)
|
|||||||
}
|
}
|
||||||
} else { // if (voice1 || voice2)
|
} else { // if (voice1 || voice2)
|
||||||
uint8_t errs = 0U;
|
uint8_t errs = 0U;
|
||||||
for (uint8_t i = 0U; i < DMR_SYNC_BYTES_LENGTH; i++) {
|
for (uint8_t i = 0U; i < DMR_SYNC_BYTES_LENGTH; i++)
|
||||||
if (voice1)
|
errs += countBits8((sync[i] & DMR_SYNC_BYTES_MASK[i]) ^ DMR_MS_VOICE_SYNC_BYTES[i]);
|
||||||
errs += countBits8((sync[i] & DMR_SYNC_BYTES_MASK[i]) ^ DMR_S2_VOICE_SYNC_BYTES[i]);
|
|
||||||
else
|
|
||||||
errs += countBits8((sync[i] & DMR_SYNC_BYTES_MASK[i]) ^ DMR_MS_VOICE_SYNC_BYTES[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errs <= MAX_SYNC_BYTES_ERRS) {
|
if (errs <= MAX_SYNC_BYTES_ERRS) {
|
||||||
if (first) {
|
if (first) {
|
||||||
m_threshold[0U] = m_threshold[1U] = m_threshold[2U] = m_threshold[3U] = threshold;
|
m_threshold[0U] = m_threshold[1U] = m_threshold[2U] = m_threshold[3U] = threshold;
|
||||||
m_centre[0U] = m_centre[1U] = m_centre[2U] = m_centre[3U] = centre;
|
m_centre[0U] = m_centre[1U] = m_centre[2U] = m_centre[3U] = centre;
|
||||||
m_averagePtr = 0U;
|
m_averagePtr = 0U;
|
||||||
m_rssiCount = 0U;
|
|
||||||
} else {
|
} else {
|
||||||
m_threshold[m_averagePtr] = threshold;
|
m_threshold[m_averagePtr] = threshold;
|
||||||
m_centre[m_averagePtr] = centre;
|
m_centre[m_averagePtr] = centre;
|
||||||
@@ -436,3 +399,27 @@ void CDMRDMORX::setColorCode(uint8_t colorCode)
|
|||||||
m_colorCode = colorCode;
|
m_colorCode = colorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CDMRDMORX::writeRSSIData(uint8_t* frame)
|
||||||
|
{
|
||||||
|
#if defined(SEND_RSSI_DATA)
|
||||||
|
// Calculate RSSI average over a burst period. We don't take into account 2.5 ms at the beginning and 2.5 ms at the end
|
||||||
|
uint16_t start = m_startPtr + DMR_SYNC_LENGTH_SAMPLES / 2U;
|
||||||
|
|
||||||
|
uint32_t accum = 0U;
|
||||||
|
for (uint16_t i = 0U; i < (DMR_FRAME_LENGTH_SAMPLES - DMR_SYNC_LENGTH_SAMPLES); i++) {
|
||||||
|
accum += m_rssi[start];
|
||||||
|
|
||||||
|
start++;
|
||||||
|
if (start >= DMO_BUFFER_LENGTH_SAMPLES)
|
||||||
|
start -= DMO_BUFFER_LENGTH_SAMPLES;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t avg = accum / (DMR_FRAME_LENGTH_SAMPLES - DMR_SYNC_LENGTH_SAMPLES);
|
||||||
|
frame[34U] = (avg >> 8) & 0xFFU;
|
||||||
|
frame[35U] = (avg >> 0) & 0xFFU;
|
||||||
|
|
||||||
|
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 3U);
|
||||||
|
#else
|
||||||
|
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|||||||
+4
-5
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "DMRDefines.h"
|
#include "DMRDefines.h"
|
||||||
|
|
||||||
const uint16_t DMO_BUFFER_LENGTH_SAMPLES = 1440U; // 60ms at 24 kHz
|
const uint16_t DMO_BUFFER_LENGTH_SAMPLES = 2880U; // 60ms at 48 kHz
|
||||||
|
|
||||||
enum DMORX_STATE {
|
enum DMORX_STATE {
|
||||||
DMORXS_NONE,
|
DMORXS_NONE,
|
||||||
@@ -58,13 +58,12 @@ private:
|
|||||||
DMORX_STATE m_state;
|
DMORX_STATE m_state;
|
||||||
uint8_t m_n;
|
uint8_t m_n;
|
||||||
uint8_t m_type;
|
uint8_t m_type;
|
||||||
uint16_t m_rssiCount;
|
uint16_t m_rssi[DMO_BUFFER_LENGTH_SAMPLES];
|
||||||
uint16_t m_rssi;
|
|
||||||
|
|
||||||
bool processSample(q15_t sample, uint16_t rssi);
|
bool processSample(q15_t sample, uint16_t rssi);
|
||||||
void correlateSync(bool first);
|
void correlateSync(bool first);
|
||||||
void samplesToBits(uint16_t start, uint8_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold);
|
void samplesToBits(uint16_t start, uint8_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold);
|
||||||
|
void writeRSSIData(uint8_t* frame);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+57
-59
@@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2009-2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2009-2017 by Jonathan Naylor G4KLX
|
||||||
* Copyright (C) 2016 by Colin Durbridge G4EML
|
* Copyright (C) 2016 by Colin Durbridge G4EML
|
||||||
|
* Copyright (C) 2017 by Andy Uribe CA6JAU
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -17,30 +18,40 @@
|
|||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// #define WANT_DEBUG
|
|
||||||
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "DMRSlotType.h"
|
#include "DMRSlotType.h"
|
||||||
|
|
||||||
#if defined(WIDE_C4FSK_FILTERS_TX)
|
// Generated using rcosdesign(0.2, 8, 10, 'sqrt') in MATLAB
|
||||||
// Generated using rcosdesign(0.2, 4, 5, 'sqrt') in MATLAB
|
static q15_t RRC_0_2_FILTER[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 850, 592, 219, -234, -720, -1179,
|
||||||
static q15_t DMR_C4FSK_FILTER[] = {688, -680, -2158, -3060, -2724, -775, 2684, 7041, 11310, 14425, 15565, 14425,
|
-1548, -1769, -1795, -1597, -1172, -544, 237, 1092, 1927, 2637,
|
||||||
11310, 7041, 2684, -775, -2724, -3060, -2158, -680, 688, 0};
|
3120, 3286, 3073, 2454, 1447, 116, -1431, -3043, -4544, -5739,
|
||||||
const uint16_t DMR_C4FSK_FILTER_LEN = 22U;
|
-6442, -6483, -5735, -4121, -1633, 1669, 5651, 10118, 14822,
|
||||||
#else
|
19484, 23810, 27520, 30367, 32156, 32767, 32156, 30367, 27520,
|
||||||
// Generated using rcosdesign(0.2, 8, 5, 'sqrt') in MATLAB
|
23810, 19484, 14822, 10118, 5651, 1669, -1633, -4121, -5735,
|
||||||
static q15_t DMR_C4FSK_FILTER[] = {401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995,
|
-6483, -6442, -5739, -4544, -3043, -1431, 116, 1447, 2454,
|
||||||
11237, 14331, 15464, 14331, 11237, 6995, 2667, -770, -2706, -3040, -2144, -675, 683, 1450, 1472, 909, 112,
|
3073, 3286, 3120, 2637, 1927, 1092, 237, -544, -1172, -1597,
|
||||||
-553, -847, -731, -340, 104, 401, 0};
|
-1795, -1769, -1548, -1179, -720, -234, 219, 592, 850}; // numTaps = 90, L = 10
|
||||||
const uint16_t DMR_C4FSK_FILTER_LEN = 42U;
|
const uint16_t RRC_0_2_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L
|
||||||
#endif
|
|
||||||
|
|
||||||
const q15_t DMR_LEVELA[] = { 640, 640 , 640, 640, 640};
|
const q15_t DMR_LEVELA = 1362;
|
||||||
const q15_t DMR_LEVELB[] = { 213, 213, 213, 213, 213};
|
const q15_t DMR_LEVELB = 454;
|
||||||
const q15_t DMR_LEVELC[] = {-213, -213, -213, -213, -213};
|
const q15_t DMR_LEVELC = -454;
|
||||||
const q15_t DMR_LEVELD[] = {-640, -640, -640, -640, -640};
|
const q15_t DMR_LEVELD = -1362;
|
||||||
|
|
||||||
|
const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
||||||
|
|
||||||
|
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
||||||
|
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
||||||
|
|
||||||
|
// PR FILL pattern
|
||||||
|
const uint8_t PR_FILL[] =
|
||||||
|
{0x63U, 0xEAU, 0x00U, 0x76U, 0x6CU, 0x76U, 0xC4U, 0x52U, 0xC8U, 0x78U,
|
||||||
|
0x09U, 0x2DU, 0xB8U, 0x79U, 0x27U, 0x57U, 0x9BU, 0x31U, 0xBCU, 0x3EU,
|
||||||
|
0xEAU, 0x45U, 0xC3U, 0x30U, 0x49U, 0x17U, 0x93U, 0xAEU, 0x8BU, 0x6DU,
|
||||||
|
0xA4U, 0xA5U, 0xADU, 0xA2U, 0xF1U, 0x35U, 0xB5U, 0x3CU, 0x1EU};
|
||||||
|
|
||||||
|
const uint8_t DMR_SYNC = 0x5FU;
|
||||||
|
|
||||||
CDMRDMOTX::CDMRDMOTX() :
|
CDMRDMOTX::CDMRDMOTX() :
|
||||||
m_fifo(),
|
m_fifo(),
|
||||||
@@ -49,14 +60,14 @@ m_modState(),
|
|||||||
m_poBuffer(),
|
m_poBuffer(),
|
||||||
m_poLen(0U),
|
m_poLen(0U),
|
||||||
m_poPtr(0U),
|
m_poPtr(0U),
|
||||||
m_txDelay(240U), // 200ms
|
m_txDelay(240U) // 200ms
|
||||||
m_count(0U)
|
|
||||||
{
|
{
|
||||||
::memset(m_modState, 0x00U, 70U * sizeof(q15_t));
|
::memset(m_modState, 0x00U, 16U * sizeof(q15_t));
|
||||||
|
|
||||||
m_modFilter.numTaps = DMR_C4FSK_FILTER_LEN;
|
m_modFilter.L = DMR_RADIO_SYMBOL_LENGTH;
|
||||||
m_modFilter.pState = m_modState;
|
m_modFilter.phaseLength = RRC_0_2_FILTER_PHASE_LEN;
|
||||||
m_modFilter.pCoeffs = DMR_C4FSK_FILTER;
|
m_modFilter.pCoeffs = RRC_0_2_FILTER;
|
||||||
|
m_modFilter.pState = m_modState;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDMRDMOTX::process()
|
void CDMRDMOTX::process()
|
||||||
@@ -64,13 +75,17 @@ void CDMRDMOTX::process()
|
|||||||
if (m_poLen == 0U && m_fifo.getData() > 0U) {
|
if (m_poLen == 0U && m_fifo.getData() > 0U) {
|
||||||
if (!m_tx) {
|
if (!m_tx) {
|
||||||
for (uint16_t i = 0U; i < m_txDelay; i++)
|
for (uint16_t i = 0U; i < m_txDelay; i++)
|
||||||
m_poBuffer[m_poLen++] = 0x00U;
|
m_poBuffer[i] = DMR_SYNC;
|
||||||
} else {
|
|
||||||
for (unsigned int i = 0U; i < 72U; i++)
|
|
||||||
m_poBuffer[m_poLen++] = 0x00U;
|
|
||||||
|
|
||||||
|
m_poLen = m_txDelay;
|
||||||
|
} else {
|
||||||
for (unsigned int i = 0U; i < DMR_FRAME_LENGTH_BYTES; i++)
|
for (unsigned int i = 0U; i < DMR_FRAME_LENGTH_BYTES; i++)
|
||||||
m_poBuffer[i] = m_fifo.get();
|
m_poBuffer[i] = m_fifo.get();
|
||||||
|
|
||||||
|
for (unsigned int i = 0U; i < 39U; i++)
|
||||||
|
m_poBuffer[i + DMR_FRAME_LENGTH_BYTES] = PR_FILL[i];
|
||||||
|
|
||||||
|
m_poLen = 72U;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_poPtr = 0U;
|
m_poPtr = 0U;
|
||||||
@@ -112,53 +127,34 @@ uint8_t CDMRDMOTX::writeData(const uint8_t* data, uint8_t length)
|
|||||||
|
|
||||||
void CDMRDMOTX::writeByte(uint8_t c)
|
void CDMRDMOTX::writeByte(uint8_t c)
|
||||||
{
|
{
|
||||||
q15_t inBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U + 1U];
|
q15_t inBuffer[4U];
|
||||||
q15_t outBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U + 1U];
|
q15_t outBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U];
|
||||||
|
|
||||||
const uint8_t MASK = 0xC0U;
|
const uint8_t MASK = 0xC0U;
|
||||||
|
|
||||||
q15_t* p = inBuffer;
|
for (uint8_t i = 0U; i < 4U; i++, c <<= 2) {
|
||||||
for (uint8_t i = 0U; i < 4U; i++, c <<= 2, p += DMR_RADIO_SYMBOL_LENGTH) {
|
|
||||||
switch (c & MASK) {
|
switch (c & MASK) {
|
||||||
case 0xC0U:
|
case 0xC0U:
|
||||||
::memcpy(p, DMR_LEVELA, DMR_RADIO_SYMBOL_LENGTH * sizeof(q15_t));
|
inBuffer[i] = DMR_LEVELA;
|
||||||
break;
|
break;
|
||||||
case 0x80U:
|
case 0x80U:
|
||||||
::memcpy(p, DMR_LEVELB, DMR_RADIO_SYMBOL_LENGTH * sizeof(q15_t));
|
inBuffer[i] = DMR_LEVELB;
|
||||||
break;
|
break;
|
||||||
case 0x00U:
|
case 0x00U:
|
||||||
::memcpy(p, DMR_LEVELC, DMR_RADIO_SYMBOL_LENGTH * sizeof(q15_t));
|
inBuffer[i] = DMR_LEVELC;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
::memcpy(p, DMR_LEVELD, DMR_RADIO_SYMBOL_LENGTH * sizeof(q15_t));
|
inBuffer[i] = DMR_LEVELD;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t blockSize = DMR_RADIO_SYMBOL_LENGTH * 4U;
|
::arm_fir_interpolate_q15(&m_modFilter, inBuffer, outBuffer, 4U);
|
||||||
|
|
||||||
// Handle the case of the oscillator not being accurate enough
|
io.write(STATE_DMR, outBuffer, DMR_RADIO_SYMBOL_LENGTH * 4U);
|
||||||
if (m_sampleCount > 0U) {
|
|
||||||
m_count += DMR_RADIO_SYMBOL_LENGTH * 4U;
|
|
||||||
|
|
||||||
if (m_count >= m_sampleCount) {
|
|
||||||
if (m_sampleInsert) {
|
|
||||||
inBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U] = inBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U - 1U];
|
|
||||||
blockSize++;
|
|
||||||
} else {
|
|
||||||
blockSize--;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_count -= m_sampleCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::arm_fir_fast_q15(&m_modFilter, inBuffer, outBuffer, blockSize);
|
|
||||||
|
|
||||||
io.write(STATE_DMR, outBuffer, blockSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t CDMRDMOTX::getSpace() const
|
uint8_t CDMRDMOTX::getSpace() const
|
||||||
{
|
{
|
||||||
return m_fifo.getSpace() / (DMR_FRAME_LENGTH_BYTES + 2U);
|
return m_fifo.getSpace() / (DMR_FRAME_LENGTH_BYTES + 2U);
|
||||||
}
|
}
|
||||||
@@ -166,5 +162,7 @@ uint16_t CDMRDMOTX::getSpace() const
|
|||||||
void CDMRDMOTX::setTXDelay(uint8_t delay)
|
void CDMRDMOTX::setTXDelay(uint8_t delay)
|
||||||
{
|
{
|
||||||
m_txDelay = 600U + uint16_t(delay) * 12U; // 500ms + tx delay
|
m_txDelay = 600U + uint16_t(delay) * 12U; // 500ms + tx delay
|
||||||
}
|
|
||||||
|
|
||||||
|
if (m_txDelay > 1200U)
|
||||||
|
m_txDelay = 1200U;
|
||||||
|
}
|
||||||
|
|||||||
+9
-10
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
|
||||||
* Copyright (C) 2016 by Colin Durbridge G4EML
|
* Copyright (C) 2016 by Colin Durbridge G4EML
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@@ -35,17 +35,16 @@ public:
|
|||||||
|
|
||||||
void setTXDelay(uint8_t delay);
|
void setTXDelay(uint8_t delay);
|
||||||
|
|
||||||
uint16_t getSpace() const;
|
uint8_t getSpace() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CSerialRB m_fifo;
|
CSerialRB m_fifo;
|
||||||
arm_fir_instance_q15 m_modFilter;
|
arm_fir_interpolate_instance_q15 m_modFilter;
|
||||||
q15_t m_modState[70U]; // NoTaps + BlockSize - 1, 42 + 20 - 1 plus some spare
|
q15_t m_modState[16U]; // blockSize + phaseLength - 1, 4 + 9 - 1 plus some spare
|
||||||
uint8_t m_poBuffer[80U];
|
uint8_t m_poBuffer[1200U];
|
||||||
uint16_t m_poLen;
|
uint16_t m_poLen;
|
||||||
uint16_t m_poPtr;
|
uint16_t m_poPtr;
|
||||||
uint16_t m_txDelay;
|
uint32_t m_txDelay;
|
||||||
uint32_t m_count;
|
|
||||||
|
|
||||||
void writeByte(uint8_t c);
|
void writeByte(uint8_t c);
|
||||||
};
|
};
|
||||||
|
|||||||
+14
-14
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2009-2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2009-2017 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
#if !defined(DMRDEFINES_H)
|
#if !defined(DMRDEFINES_H)
|
||||||
#define DMRDEFINES_H
|
#define DMRDEFINES_H
|
||||||
|
|
||||||
const unsigned int DMR_RADIO_SYMBOL_LENGTH = 5U; // At 24 kHz sample rate
|
const unsigned int DMR_RADIO_SYMBOL_LENGTH = 10U; // At 48 kHz sample rate
|
||||||
|
|
||||||
const unsigned int DMR_FRAME_LENGTH_BYTES = 33U;
|
const unsigned int DMR_FRAME_LENGTH_BYTES = 33U;
|
||||||
const unsigned int DMR_FRAME_LENGTH_BITS = DMR_FRAME_LENGTH_BYTES * 8U;
|
const unsigned int DMR_FRAME_LENGTH_BITS = DMR_FRAME_LENGTH_BYTES * 8U;
|
||||||
@@ -61,32 +61,32 @@ const uint8_t DMR_MS_DATA_SYNC_BYTES[] = {0x0DU, 0x5DU, 0x7FU, 0x77U, 0xFDU, 0
|
|||||||
const uint8_t DMR_MS_VOICE_SYNC_BYTES[] = {0x07U, 0xF7U, 0xD5U, 0xDDU, 0x57U, 0xDFU, 0xD0U};
|
const uint8_t DMR_MS_VOICE_SYNC_BYTES[] = {0x07U, 0xF7U, 0xD5U, 0xDDU, 0x57U, 0xDFU, 0xD0U};
|
||||||
const uint8_t DMR_BS_DATA_SYNC_BYTES[] = {0x0DU, 0xFFU, 0x57U, 0xD7U, 0x5DU, 0xF5U, 0xD0U};
|
const uint8_t DMR_BS_DATA_SYNC_BYTES[] = {0x0DU, 0xFFU, 0x57U, 0xD7U, 0x5DU, 0xF5U, 0xD0U};
|
||||||
const uint8_t DMR_BS_VOICE_SYNC_BYTES[] = {0x07U, 0x55U, 0xFDU, 0x7DU, 0xF7U, 0x5FU, 0x70U};
|
const uint8_t DMR_BS_VOICE_SYNC_BYTES[] = {0x07U, 0x55U, 0xFDU, 0x7DU, 0xF7U, 0x5FU, 0x70U};
|
||||||
const uint8_t DMR_S1_DATA_SYNC_BYTES[] = {0x0FU, 0x7FU, 0xDDU, 0x5DU, 0xDFU, 0xD5U, 0x50U};
|
|
||||||
const uint8_t DMR_S1_VOICE_SYNC_BYTES[] = {0x05U, 0xD5U, 0x77U, 0xF7U, 0x75U, 0x7FU, 0xF0U};
|
|
||||||
const uint8_t DMR_S2_DATA_SYNC_BYTES[] = {0x0DU, 0x75U, 0x57U, 0xF5U, 0xFFU, 0x7FU, 0x50U};
|
|
||||||
const uint8_t DMR_S2_VOICE_SYNC_BYTES[] = {0x07U, 0xDFU, 0xFDU, 0x5FU, 0x55U, 0xD5U, 0xF0U};
|
|
||||||
const uint8_t DMR_SYNC_BYTES_MASK[] = {0x0FU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xF0U};
|
const uint8_t DMR_SYNC_BYTES_MASK[] = {0x0FU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xF0U};
|
||||||
|
|
||||||
const uint64_t DMR_MS_DATA_SYNC_BITS = 0x0000D5D7F77FD757U;
|
const uint64_t DMR_MS_DATA_SYNC_BITS = 0x0000D5D7F77FD757U;
|
||||||
const uint64_t DMR_MS_VOICE_SYNC_BITS = 0x00007F7D5DD57DFDU;
|
const uint64_t DMR_MS_VOICE_SYNC_BITS = 0x00007F7D5DD57DFDU;
|
||||||
const uint64_t DMR_BS_DATA_SYNC_BITS = 0x0000DFF57D75DF5DU;
|
const uint64_t DMR_BS_DATA_SYNC_BITS = 0x0000DFF57D75DF5DU;
|
||||||
const uint64_t DMR_BS_VOICE_SYNC_BITS = 0x0000755FD7DF75F7U;
|
const uint64_t DMR_BS_VOICE_SYNC_BITS = 0x0000755FD7DF75F7U;
|
||||||
const uint64_t DMR_S1_DATA_SYNC_BITS = 0x0000F7FDD5DDFD55U;
|
|
||||||
const uint64_t DMR_S1_VOICE_SYNC_BITS = 0x00005D577F7757FFU;
|
|
||||||
const uint64_t DMR_S2_DATA_SYNC_BITS = 0x0000D7557F5FF7F5U;
|
|
||||||
const uint64_t DMR_S2_VOICE_SYNC_BITS = 0x00007DFFD5F55D5FU;
|
|
||||||
const uint64_t DMR_SYNC_BITS_MASK = 0x0000FFFFFFFFFFFFU;
|
const uint64_t DMR_SYNC_BITS_MASK = 0x0000FFFFFFFFFFFFU;
|
||||||
|
|
||||||
const uint32_t DMR_MS_DATA_SYNC_SYMBOLS = 0x0076286EU;
|
const uint32_t DMR_MS_DATA_SYNC_SYMBOLS = 0x0076286EU;
|
||||||
const uint32_t DMR_MS_VOICE_SYNC_SYMBOLS = 0x0089D791U;
|
const uint32_t DMR_MS_VOICE_SYNC_SYMBOLS = 0x0089D791U;
|
||||||
const uint32_t DMR_BS_DATA_SYNC_SYMBOLS = 0x00439B4DU;
|
const uint32_t DMR_BS_DATA_SYNC_SYMBOLS = 0x00439B4DU;
|
||||||
const uint32_t DMR_BS_VOICE_SYNC_SYMBOLS = 0x00BC64B2U;
|
const uint32_t DMR_BS_VOICE_SYNC_SYMBOLS = 0x00BC64B2U;
|
||||||
const uint32_t DMR_S1_DATA_SYNC_SYMBOLS = 0x0021751FU;
|
|
||||||
const uint32_t DMR_S1_VOICE_SYNC_SYMBOLS = 0x00DE8AE0U;
|
|
||||||
const uint32_t DMR_S2_DATA_SYNC_SYMBOLS = 0x006F8C23U;
|
|
||||||
const uint32_t DMR_S2_VOICE_SYNC_SYMBOLS = 0x009073DCU;
|
|
||||||
const uint32_t DMR_SYNC_SYMBOLS_MASK = 0x00FFFFFFU;
|
const uint32_t DMR_SYNC_SYMBOLS_MASK = 0x00FFFFFFU;
|
||||||
|
|
||||||
|
// D 5 D 7 F 7 7 F D 7 5 7
|
||||||
|
// 11 01 01 01 11 01 01 11 11 11 01 11 01 11 11 11 11 01 01 11 01 01 01 11
|
||||||
|
// -3 +3 +3 +3 -3 +3 +3 -3 -3 -3 +3 -3 +3 -3 -3 -3 -3 +3 +3 -3 +3 +3 +3 -3
|
||||||
|
|
||||||
|
const int8_t DMR_MS_DATA_SYNC_SYMBOLS_VALUES[] = {-3, +3, +3, +3, -3, +3, +3, -3, -3, -3, +3, -3, +3, -3, -3, -3, -3, +3, +3, -3, +3, +3, +3, -3};
|
||||||
|
|
||||||
|
// 7 F 7 D 5 D D 5 7 D F D
|
||||||
|
// 01 11 11 11 01 11 11 01 01 01 11 01 11 01 01 01 01 11 11 01 11 11 11 01
|
||||||
|
// +3 -3 -3 -3 +3 -3 -3 +3 +3 +3 -3 +3 -3 +3 +3 +3 +3 -3 -3 +3 -3 -3 -3 +3
|
||||||
|
|
||||||
|
const int8_t DMR_MS_VOICE_SYNC_SYMBOLS_VALUES[] = {+3, -3, -3, -3, +3, -3, -3, +3, +3, +3, -3, +3, -3, +3, +3, +3, +3, -3, -3, +3, -3, -3, -3, +3};
|
||||||
|
|
||||||
const uint8_t DT_VOICE_PI_HEADER = 0U;
|
const uint8_t DT_VOICE_PI_HEADER = 0U;
|
||||||
const uint8_t DT_VOICE_LC_HEADER = 1U;
|
const uint8_t DT_VOICE_LC_HEADER = 1U;
|
||||||
const uint8_t DT_TERMINATOR_WITH_LC = 2U;
|
const uint8_t DT_TERMINATOR_WITH_LC = 2U;
|
||||||
|
|||||||
+24
-15
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2009-2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2009-2017 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -16,8 +16,6 @@
|
|||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define WANT_DEBUG
|
|
||||||
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "DMRIdleRX.h"
|
#include "DMRIdleRX.h"
|
||||||
@@ -26,8 +24,8 @@
|
|||||||
|
|
||||||
const q15_t SCALING_FACTOR = 19505; // Q15(0.60)
|
const q15_t SCALING_FACTOR = 19505; // Q15(0.60)
|
||||||
|
|
||||||
const uint8_t MAX_SYNC_SYMBOLS_ERRS = 2U;
|
const uint8_t MAX_SYNC_SYMBOLS_ERRS = 4U;
|
||||||
const uint8_t MAX_SYNC_BYTES_ERRS = 3U;
|
const uint8_t MAX_SYNC_BYTES_ERRS = 6U;
|
||||||
|
|
||||||
const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
||||||
|
|
||||||
@@ -84,16 +82,28 @@ void CDMRIdleRX::processSample(q15_t sample)
|
|||||||
q15_t max = -16000;
|
q15_t max = -16000;
|
||||||
q15_t min = 16000;
|
q15_t min = 16000;
|
||||||
|
|
||||||
uint32_t mask = 0x00800000U;
|
for (uint8_t i = 0U; i < DMR_SYNC_LENGTH_SYMBOLS; i++) {
|
||||||
for (uint8_t i = 0U; i < DMR_SYNC_LENGTH_SYMBOLS; i++, mask >>= 1) {
|
q15_t val = m_buffer[ptr];
|
||||||
bool b = (DMR_MS_DATA_SYNC_SYMBOLS & mask) == mask;
|
|
||||||
|
|
||||||
if (m_buffer[ptr] > max)
|
if (val > max)
|
||||||
max = m_buffer[ptr];
|
max = val;
|
||||||
if (m_buffer[ptr] < min)
|
if (val < min)
|
||||||
min = m_buffer[ptr];
|
min = val;
|
||||||
|
|
||||||
corr += b ? -m_buffer[ptr] : m_buffer[ptr];
|
switch (DMR_MS_DATA_SYNC_SYMBOLS_VALUES[i]) {
|
||||||
|
case +3:
|
||||||
|
corr -= (val + val + val);
|
||||||
|
break;
|
||||||
|
case +1:
|
||||||
|
corr -= val;
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
corr += val;
|
||||||
|
break;
|
||||||
|
default: // -3
|
||||||
|
corr += (val + val + val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
ptr += DMR_RADIO_SYMBOL_LENGTH;
|
ptr += DMR_RADIO_SYMBOL_LENGTH;
|
||||||
if (ptr >= DMR_FRAME_LENGTH_SAMPLES)
|
if (ptr >= DMR_FRAME_LENGTH_SAMPLES)
|
||||||
@@ -150,7 +160,7 @@ void CDMRIdleRX::processSample(q15_t sample)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_endPtr = NOENDPTR;
|
m_endPtr = NOENDPTR;
|
||||||
m_maxCorr = 0U;
|
m_maxCorr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dataPtr++;
|
m_dataPtr++;
|
||||||
@@ -199,4 +209,3 @@ void CDMRIdleRX::setColorCode(uint8_t colorCode)
|
|||||||
{
|
{
|
||||||
m_colorCode = colorCode;
|
m_colorCode = colorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -43,8 +43,8 @@ private:
|
|||||||
q15_t m_threshold;
|
q15_t m_threshold;
|
||||||
uint8_t m_colorCode;
|
uint8_t m_colorCode;
|
||||||
|
|
||||||
void processSample(q15_t sample);
|
void processSample(q15_t sample);
|
||||||
void samplesToBits(uint16_t start, uint8_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold);
|
void samplesToBits(uint16_t start, uint8_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+61
-64
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2009-2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2009-2017 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -16,23 +16,21 @@
|
|||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define WANT_DEBUG
|
|
||||||
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "DMRSlotRX.h"
|
#include "DMRSlotRX.h"
|
||||||
#include "DMRSlotType.h"
|
#include "DMRSlotType.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
const uint16_t SCAN_START = 400U;
|
const uint16_t SCAN_START = 790U;
|
||||||
const uint16_t SCAN_END = 490U;
|
const uint16_t SCAN_END = 920U;
|
||||||
|
|
||||||
const q15_t SCALING_FACTOR = 19505; // Q15(0.60)
|
const q15_t SCALING_FACTOR = 19505; // Q15(0.60)
|
||||||
|
|
||||||
const uint8_t MAX_SYNC_SYMBOLS_ERRS = 2U;
|
const uint8_t MAX_SYNC_SYMBOLS_ERRS = 4U;
|
||||||
const uint8_t MAX_SYNC_BYTES_ERRS = 3U;
|
const uint8_t MAX_SYNC_BYTES_ERRS = 6U;
|
||||||
|
|
||||||
const uint8_t MAX_SYNC_LOST_FRAMES = 13U;
|
const uint8_t MAX_SYNC_LOST_FRAMES = 26U;
|
||||||
|
|
||||||
const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
||||||
|
|
||||||
@@ -65,8 +63,7 @@ m_delay(0U),
|
|||||||
m_state(DMRRXS_NONE),
|
m_state(DMRRXS_NONE),
|
||||||
m_n(0U),
|
m_n(0U),
|
||||||
m_type(0U),
|
m_type(0U),
|
||||||
m_rssiCount(0U),
|
m_rssi()
|
||||||
m_rssi(0U)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +88,6 @@ void CDMRSlotRX::reset()
|
|||||||
m_state = DMRRXS_NONE;
|
m_state = DMRRXS_NONE;
|
||||||
m_startPtr = 0U;
|
m_startPtr = 0U;
|
||||||
m_endPtr = NOENDPTR;
|
m_endPtr = NOENDPTR;
|
||||||
m_rssiCount = 0U;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi)
|
bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi)
|
||||||
@@ -101,10 +97,11 @@ bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi)
|
|||||||
return m_state != DMRRXS_NONE;
|
return m_state != DMRRXS_NONE;
|
||||||
|
|
||||||
// Ensure that the buffer doesn't overflow
|
// Ensure that the buffer doesn't overflow
|
||||||
if (m_dataPtr > m_endPtr || m_dataPtr >= 900U)
|
if (m_dataPtr > m_endPtr || m_dataPtr >= 1900U)
|
||||||
return m_state != DMRRXS_NONE;
|
return m_state != DMRRXS_NONE;
|
||||||
|
|
||||||
m_buffer[m_dataPtr] = sample;
|
m_buffer[m_dataPtr] = sample;
|
||||||
|
m_rssi[m_dataPtr] = rssi;
|
||||||
|
|
||||||
m_bitBuffer[m_bitPtr] <<= 1;
|
m_bitBuffer[m_bitPtr] <<= 1;
|
||||||
if (sample < 0)
|
if (sample < 0)
|
||||||
@@ -114,9 +111,6 @@ bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi)
|
|||||||
if (m_dataPtr >= SCAN_START && m_dataPtr <= SCAN_END)
|
if (m_dataPtr >= SCAN_START && m_dataPtr <= SCAN_END)
|
||||||
correlateSync(true);
|
correlateSync(true);
|
||||||
} else {
|
} else {
|
||||||
// Grab the RSSI data during the frame
|
|
||||||
if (m_state == DMRRXS_VOICE && m_dataPtr == m_syncPtr)
|
|
||||||
m_rssi = rssi;
|
|
||||||
|
|
||||||
uint16_t min = m_syncPtr - 1U;
|
uint16_t min = m_syncPtr - 1U;
|
||||||
uint16_t max = m_syncPtr + 1U;
|
uint16_t max = m_syncPtr + 1U;
|
||||||
@@ -151,7 +145,7 @@ bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi)
|
|||||||
switch (dataType) {
|
switch (dataType) {
|
||||||
case DT_DATA_HEADER:
|
case DT_DATA_HEADER:
|
||||||
DEBUG5("DMRSlotRX: data header found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold);
|
DEBUG5("DMRSlotRX: data header found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold);
|
||||||
serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
writeRSSIData(frame);
|
||||||
m_state = DMRRXS_DATA;
|
m_state = DMRRXS_DATA;
|
||||||
m_type = 0x00U;
|
m_type = 0x00U;
|
||||||
break;
|
break;
|
||||||
@@ -160,33 +154,33 @@ bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi)
|
|||||||
case DT_RATE_1_DATA:
|
case DT_RATE_1_DATA:
|
||||||
if (m_state == DMRRXS_DATA) {
|
if (m_state == DMRRXS_DATA) {
|
||||||
DEBUG5("DMRSlotRX: data payload found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold);
|
DEBUG5("DMRSlotRX: data payload found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold);
|
||||||
serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
writeRSSIData(frame);
|
||||||
m_type = dataType;
|
m_type = dataType;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DT_VOICE_LC_HEADER:
|
case DT_VOICE_LC_HEADER:
|
||||||
DEBUG5("DMRSlotRX: voice header found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold);
|
DEBUG5("DMRSlotRX: voice header found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold);
|
||||||
serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
writeRSSIData(frame);
|
||||||
m_state = DMRRXS_VOICE;
|
m_state = DMRRXS_VOICE;
|
||||||
break;
|
break;
|
||||||
case DT_VOICE_PI_HEADER:
|
case DT_VOICE_PI_HEADER:
|
||||||
if (m_state == DMRRXS_VOICE) {
|
if (m_state == DMRRXS_VOICE) {
|
||||||
DEBUG5("DMRSlotRX: voice pi header found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold);
|
DEBUG5("DMRSlotRX: voice pi header found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold);
|
||||||
serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
writeRSSIData(frame);
|
||||||
}
|
}
|
||||||
m_state = DMRRXS_VOICE;
|
m_state = DMRRXS_VOICE;
|
||||||
break;
|
break;
|
||||||
case DT_TERMINATOR_WITH_LC:
|
case DT_TERMINATOR_WITH_LC:
|
||||||
if (m_state == DMRRXS_VOICE) {
|
if (m_state == DMRRXS_VOICE) {
|
||||||
DEBUG5("DMRSlotRX: voice terminator found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold);
|
DEBUG5("DMRSlotRX: voice terminator found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold);
|
||||||
serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
writeRSSIData(frame);
|
||||||
m_state = DMRRXS_NONE;
|
m_state = DMRRXS_NONE;
|
||||||
m_endPtr = NOENDPTR;
|
m_endPtr = NOENDPTR;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: // DT_CSBK
|
default: // DT_CSBK
|
||||||
DEBUG5("DMRSlotRX: csbk found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold);
|
DEBUG5("DMRSlotRX: csbk found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold);
|
||||||
serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
writeRSSIData(frame);
|
||||||
m_state = DMRRXS_NONE;
|
m_state = DMRRXS_NONE;
|
||||||
m_endPtr = NOENDPTR;
|
m_endPtr = NOENDPTR;
|
||||||
break;
|
break;
|
||||||
@@ -195,22 +189,7 @@ bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi)
|
|||||||
} else if (m_control == CONTROL_VOICE) {
|
} else if (m_control == CONTROL_VOICE) {
|
||||||
// Voice sync
|
// Voice sync
|
||||||
DEBUG5("DMRSlotRX: voice sync found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold);
|
DEBUG5("DMRSlotRX: voice sync found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold);
|
||||||
#if defined(SEND_RSSI_DATA)
|
writeRSSIData(frame);
|
||||||
// Send RSSI data approximately every second
|
|
||||||
if (m_rssiCount == 2U) {
|
|
||||||
frame[34U] = (m_rssi >> 8) & 0xFFU;
|
|
||||||
frame[35U] = (m_rssi >> 0) & 0xFFU;
|
|
||||||
serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 3U);
|
|
||||||
} else {
|
|
||||||
serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_rssiCount++;
|
|
||||||
if (m_rssiCount >= 16U)
|
|
||||||
m_rssiCount = 0U;
|
|
||||||
#else
|
|
||||||
serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
|
||||||
#endif
|
|
||||||
m_state = DMRRXS_VOICE;
|
m_state = DMRRXS_VOICE;
|
||||||
m_syncCount = 0U;
|
m_syncCount = 0U;
|
||||||
m_n = 0U;
|
m_n = 0U;
|
||||||
@@ -231,26 +210,12 @@ bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi)
|
|||||||
} else {
|
} else {
|
||||||
frame[0U] = ++m_n;
|
frame[0U] = ++m_n;
|
||||||
}
|
}
|
||||||
#if defined(SEND_RSSI_DATA)
|
|
||||||
// Send RSSI data approximately every second
|
|
||||||
if (m_rssiCount == 2U) {
|
|
||||||
frame[34U] = (m_rssi >> 8) & 0xFFU;
|
|
||||||
frame[35U] = (m_rssi >> 0) & 0xFFU;
|
|
||||||
serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 3U);
|
|
||||||
} else {
|
|
||||||
serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_rssiCount++;
|
|
||||||
if (m_rssiCount >= 16U)
|
|
||||||
m_rssiCount = 0U;
|
|
||||||
#else
|
|
||||||
serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
||||||
#endif
|
|
||||||
} else if (m_state == DMRRXS_DATA) {
|
} else if (m_state == DMRRXS_DATA) {
|
||||||
if (m_type != 0x00U) {
|
if (m_type != 0x00U) {
|
||||||
frame[0U] = CONTROL_DATA | m_type;
|
frame[0U] = CONTROL_DATA | m_type;
|
||||||
serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
writeRSSIData(frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -280,19 +245,34 @@ void CDMRSlotRX::correlateSync(bool first)
|
|||||||
q15_t min = 16000;
|
q15_t min = 16000;
|
||||||
q15_t max = -16000;
|
q15_t max = -16000;
|
||||||
|
|
||||||
uint32_t mask = 0x00800000U;
|
for (uint8_t i = 0U; i < DMR_SYNC_LENGTH_SYMBOLS; i++) {
|
||||||
for (uint8_t i = 0U; i < DMR_SYNC_LENGTH_SYMBOLS; i++, mask >>= 1) {
|
q15_t val = m_buffer[ptr];
|
||||||
bool b = (DMR_MS_DATA_SYNC_SYMBOLS & mask) == mask;
|
|
||||||
|
|
||||||
if (m_buffer[ptr] > max)
|
if (val > max)
|
||||||
max = m_buffer[ptr];
|
max = val;
|
||||||
if (m_buffer[ptr] < min)
|
if (val < min)
|
||||||
min = m_buffer[ptr];
|
min = val;
|
||||||
|
|
||||||
|
int8_t corrVal;
|
||||||
if (data)
|
if (data)
|
||||||
corr += b ? -m_buffer[ptr] : m_buffer[ptr];
|
corrVal = DMR_MS_DATA_SYNC_SYMBOLS_VALUES[i];
|
||||||
else // if (voice)
|
else
|
||||||
corr += b ? m_buffer[ptr] : -m_buffer[ptr];
|
corrVal = DMR_MS_VOICE_SYNC_SYMBOLS_VALUES[i];
|
||||||
|
|
||||||
|
switch (corrVal) {
|
||||||
|
case +3:
|
||||||
|
corr -= (val + val + val);
|
||||||
|
break;
|
||||||
|
case +1:
|
||||||
|
corr -= val;
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
corr += val;
|
||||||
|
break;
|
||||||
|
default: // -3
|
||||||
|
corr += (val + val + val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
ptr += DMR_RADIO_SYMBOL_LENGTH;
|
ptr += DMR_RADIO_SYMBOL_LENGTH;
|
||||||
}
|
}
|
||||||
@@ -317,7 +297,6 @@ void CDMRSlotRX::correlateSync(bool first)
|
|||||||
m_threshold[0U] = m_threshold[1U] = m_threshold[2U] = m_threshold[3U] = threshold;
|
m_threshold[0U] = m_threshold[1U] = m_threshold[2U] = m_threshold[3U] = threshold;
|
||||||
m_centre[0U] = m_centre[1U] = m_centre[2U] = m_centre[3U] = centre;
|
m_centre[0U] = m_centre[1U] = m_centre[2U] = m_centre[3U] = centre;
|
||||||
m_averagePtr = 0U;
|
m_averagePtr = 0U;
|
||||||
m_rssiCount = 0U;
|
|
||||||
} else {
|
} else {
|
||||||
m_threshold[m_averagePtr] = threshold;
|
m_threshold[m_averagePtr] = threshold;
|
||||||
m_centre[m_averagePtr] = centre;
|
m_centre[m_averagePtr] = centre;
|
||||||
@@ -343,7 +322,6 @@ void CDMRSlotRX::correlateSync(bool first)
|
|||||||
m_threshold[0U] = m_threshold[1U] = m_threshold[2U] = m_threshold[3U] = threshold;
|
m_threshold[0U] = m_threshold[1U] = m_threshold[2U] = m_threshold[3U] = threshold;
|
||||||
m_centre[0U] = m_centre[1U] = m_centre[2U] = m_centre[3U] = centre;
|
m_centre[0U] = m_centre[1U] = m_centre[2U] = m_centre[3U] = centre;
|
||||||
m_averagePtr = 0U;
|
m_averagePtr = 0U;
|
||||||
m_rssiCount = 0U;
|
|
||||||
} else {
|
} else {
|
||||||
m_threshold[m_averagePtr] = threshold;
|
m_threshold[m_averagePtr] = threshold;
|
||||||
m_centre[m_averagePtr] = centre;
|
m_centre[m_averagePtr] = centre;
|
||||||
@@ -403,3 +381,22 @@ void CDMRSlotRX::setDelay(uint8_t delay)
|
|||||||
m_delay = delay;
|
m_delay = delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CDMRSlotRX::writeRSSIData(uint8_t* frame)
|
||||||
|
{
|
||||||
|
#if defined(SEND_RSSI_DATA)
|
||||||
|
// Calculate RSSI average over a burst period. We don't take into account 2.5 ms at the beginning and 2.5 ms at the end
|
||||||
|
uint16_t start = m_startPtr + DMR_SYNC_LENGTH_SAMPLES / 2U;
|
||||||
|
|
||||||
|
uint32_t accum = 0U;
|
||||||
|
for (uint16_t i = 0U; i < (DMR_FRAME_LENGTH_SAMPLES - DMR_SYNC_LENGTH_SAMPLES); i++)
|
||||||
|
accum += m_rssi[start++];
|
||||||
|
|
||||||
|
uint16_t avg = accum / (DMR_FRAME_LENGTH_SAMPLES - DMR_SYNC_LENGTH_SAMPLES);
|
||||||
|
frame[34U] = (avg >> 8) & 0xFFU;
|
||||||
|
frame[35U] = (avg >> 0) & 0xFFU;
|
||||||
|
|
||||||
|
serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 3U);
|
||||||
|
#else
|
||||||
|
serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|||||||
+4
-5
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -44,7 +44,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
bool m_slot;
|
bool m_slot;
|
||||||
uint32_t m_bitBuffer[DMR_RADIO_SYMBOL_LENGTH];
|
uint32_t m_bitBuffer[DMR_RADIO_SYMBOL_LENGTH];
|
||||||
q15_t m_buffer[900U];
|
q15_t m_buffer[1900U];
|
||||||
uint16_t m_bitPtr;
|
uint16_t m_bitPtr;
|
||||||
uint16_t m_dataPtr;
|
uint16_t m_dataPtr;
|
||||||
uint16_t m_syncPtr;
|
uint16_t m_syncPtr;
|
||||||
@@ -62,12 +62,11 @@ private:
|
|||||||
DMRRX_STATE m_state;
|
DMRRX_STATE m_state;
|
||||||
uint8_t m_n;
|
uint8_t m_n;
|
||||||
uint8_t m_type;
|
uint8_t m_type;
|
||||||
uint16_t m_rssiCount;
|
uint16_t m_rssi[1900U];
|
||||||
uint16_t m_rssi;
|
|
||||||
|
|
||||||
void correlateSync(bool first);
|
void correlateSync(bool first);
|
||||||
void samplesToBits(uint16_t start, uint8_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold);
|
void samplesToBits(uint16_t start, uint8_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold);
|
||||||
|
void writeRSSIData(uint8_t* frame);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2009-2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2009-2017 by Jonathan Naylor G4KLX
|
||||||
* Copyright (C) 2016 by Colin Durbridge G4EML
|
* Copyright (C) 2016 by Colin Durbridge G4EML
|
||||||
|
* Copyright (C) 2017 by Andy Uribe CA6JAU
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -17,31 +18,28 @@
|
|||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// #define WANT_DEBUG
|
|
||||||
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "DMRSlotType.h"
|
#include "DMRSlotType.h"
|
||||||
|
|
||||||
#if defined(WIDE_C4FSK_FILTERS_TX)
|
// Generated using rcosdesign(0.2, 8, 10, 'sqrt') in MATLAB
|
||||||
// Generated using rcosdesign(0.2, 4, 5, 'sqrt') in MATLAB
|
static q15_t RRC_0_2_FILTER[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 850, 592, 219, -234, -720, -1179,
|
||||||
static q15_t DMR_C4FSK_FILTER[] = {688, -680, -2158, -3060, -2724, -775, 2684, 7041, 11310, 14425, 15565, 14425,
|
-1548, -1769, -1795, -1597, -1172, -544, 237, 1092, 1927, 2637,
|
||||||
11310, 7041, 2684, -775, -2724, -3060, -2158, -680, 688, 0};
|
3120, 3286, 3073, 2454, 1447, 116, -1431, -3043, -4544, -5739,
|
||||||
const uint16_t DMR_C4FSK_FILTER_LEN = 22U;
|
-6442, -6483, -5735, -4121, -1633, 1669, 5651, 10118, 14822,
|
||||||
#else
|
19484, 23810, 27520, 30367, 32156, 32767, 32156, 30367, 27520,
|
||||||
// Generated using rcosdesign(0.2, 8, 5, 'sqrt') in MATLAB
|
23810, 19484, 14822, 10118, 5651, 1669, -1633, -4121, -5735,
|
||||||
static q15_t DMR_C4FSK_FILTER[] = {401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995,
|
-6483, -6442, -5739, -4544, -3043, -1431, 116, 1447, 2454,
|
||||||
11237, 14331, 15464, 14331, 11237, 6995, 2667, -770, -2706, -3040, -2144, -675, 683, 1450, 1472, 909, 112,
|
3073, 3286, 3120, 2637, 1927, 1092, 237, -544, -1172, -1597,
|
||||||
-553, -847, -731, -340, 104, 401, 0};
|
-1795, -1769, -1548, -1179, -720, -234, 219, 592, 850}; // numTaps = 90, L = 10
|
||||||
const uint16_t DMR_C4FSK_FILTER_LEN = 42U;
|
const uint16_t RRC_0_2_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L
|
||||||
#endif
|
|
||||||
|
|
||||||
const q15_t DMR_LEVELA[] = { 640, 640 , 640, 640, 640};
|
const q15_t DMR_LEVELA = 1362;
|
||||||
const q15_t DMR_LEVELB[] = { 213, 213, 213, 213, 213};
|
const q15_t DMR_LEVELB = 454;
|
||||||
const q15_t DMR_LEVELC[] = {-213, -213, -213, -213, -213};
|
const q15_t DMR_LEVELC = -454;
|
||||||
const q15_t DMR_LEVELD[] = {-640, -640, -640, -640, -640};
|
const q15_t DMR_LEVELD = -1362;
|
||||||
|
|
||||||
// The PR FILL and Data Sync pattern.
|
// The PR FILL and BS Data Sync pattern.
|
||||||
const uint8_t IDLE_DATA[] =
|
const uint8_t IDLE_DATA[] =
|
||||||
{0x53U, 0xC2U, 0x5EU, 0xABU, 0xA8U, 0x67U, 0x1DU, 0xC7U, 0x38U, 0x3BU, 0xD9U,
|
{0x53U, 0xC2U, 0x5EU, 0xABU, 0xA8U, 0x67U, 0x1DU, 0xC7U, 0x38U, 0x3BU, 0xD9U,
|
||||||
0x36U, 0x00U, 0x0DU, 0xFFU, 0x57U, 0xD7U, 0x5DU, 0xF5U, 0xD0U, 0x03U, 0xF6U,
|
0x36U, 0x00U, 0x0DU, 0xFFU, 0x57U, 0xD7U, 0x5DU, 0xF5U, 0xD0U, 0x03U, 0xF6U,
|
||||||
@@ -61,6 +59,9 @@ const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02
|
|||||||
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
||||||
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
||||||
|
|
||||||
|
const uint32_t STARTUP_COUNT = 20U;
|
||||||
|
const uint32_t ABORT_COUNT = 6U;
|
||||||
|
|
||||||
CDMRTX::CDMRTX() :
|
CDMRTX::CDMRTX() :
|
||||||
m_fifo(),
|
m_fifo(),
|
||||||
m_modFilter(),
|
m_modFilter(),
|
||||||
@@ -74,20 +75,25 @@ m_markBuffer(),
|
|||||||
m_poBuffer(),
|
m_poBuffer(),
|
||||||
m_poLen(0U),
|
m_poLen(0U),
|
||||||
m_poPtr(0U),
|
m_poPtr(0U),
|
||||||
m_count(0U),
|
m_frameCount(0U),
|
||||||
|
m_abortCount(),
|
||||||
m_abort()
|
m_abort()
|
||||||
{
|
{
|
||||||
::memset(m_modState, 0x00U, 70U * sizeof(q15_t));
|
::memset(m_modState, 0x00U, 16U * sizeof(q15_t));
|
||||||
|
|
||||||
m_modFilter.numTaps = DMR_C4FSK_FILTER_LEN;
|
m_modFilter.L = DMR_RADIO_SYMBOL_LENGTH;
|
||||||
m_modFilter.pState = m_modState;
|
m_modFilter.phaseLength = RRC_0_2_FILTER_PHASE_LEN;
|
||||||
m_modFilter.pCoeffs = DMR_C4FSK_FILTER;
|
m_modFilter.pCoeffs = RRC_0_2_FILTER;
|
||||||
|
m_modFilter.pState = m_modState;
|
||||||
|
|
||||||
::memcpy(m_newShortLC, EMPTY_SHORT_LC, 12U);
|
::memcpy(m_newShortLC, EMPTY_SHORT_LC, 12U);
|
||||||
::memcpy(m_shortLC, EMPTY_SHORT_LC, 12U);
|
::memcpy(m_shortLC, EMPTY_SHORT_LC, 12U);
|
||||||
|
|
||||||
m_abort[0U] = false;
|
m_abort[0U] = false;
|
||||||
m_abort[1U] = false;
|
m_abort[1U] = false;
|
||||||
|
|
||||||
|
m_abortCount[0U] = 0U;
|
||||||
|
m_abortCount[1U] = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDMRTX::process()
|
void CDMRTX::process()
|
||||||
@@ -215,10 +221,12 @@ uint8_t CDMRTX::writeAbort(const uint8_t* data, uint8_t length)
|
|||||||
|
|
||||||
switch (data[0U]) {
|
switch (data[0U]) {
|
||||||
case 1U:
|
case 1U:
|
||||||
|
m_abortCount[0U] = 0U;
|
||||||
m_abort[0U] = true;
|
m_abort[0U] = true;
|
||||||
return 0U;
|
return 0U;
|
||||||
|
|
||||||
case 2U:
|
case 2U:
|
||||||
|
m_abortCount[1U] = 0U;
|
||||||
m_abort[1U] = true;
|
m_abort[1U] = true;
|
||||||
return 0U;
|
return 0U;
|
||||||
|
|
||||||
@@ -231,7 +239,9 @@ void CDMRTX::setStart(bool start)
|
|||||||
{
|
{
|
||||||
m_state = start ? DMRTXSTATE_SLOT1 : DMRTXSTATE_IDLE;
|
m_state = start ? DMRTXSTATE_SLOT1 : DMRTXSTATE_IDLE;
|
||||||
|
|
||||||
m_count = 0U;
|
m_frameCount = 0U;
|
||||||
|
m_abortCount[0U] = 0U;
|
||||||
|
m_abortCount[1U] = 0U;
|
||||||
|
|
||||||
m_abort[0U] = false;
|
m_abort[0U] = false;
|
||||||
m_abort[1U] = false;
|
m_abort[1U] = false;
|
||||||
@@ -240,80 +250,54 @@ void CDMRTX::setStart(bool start)
|
|||||||
void CDMRTX::setCal(bool start)
|
void CDMRTX::setCal(bool start)
|
||||||
{
|
{
|
||||||
m_state = start ? DMRTXSTATE_CAL : DMRTXSTATE_IDLE;
|
m_state = start ? DMRTXSTATE_CAL : DMRTXSTATE_IDLE;
|
||||||
|
|
||||||
m_count = 0U;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDMRTX::writeByte(uint8_t c, uint8_t control)
|
void CDMRTX::writeByte(uint8_t c, uint8_t control)
|
||||||
{
|
{
|
||||||
q15_t inBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U + 1U];
|
q15_t inBuffer[4U];
|
||||||
q15_t outBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U + 1U];
|
q15_t outBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U];
|
||||||
|
|
||||||
const uint8_t MASK = 0xC0U;
|
const uint8_t MASK = 0xC0U;
|
||||||
|
|
||||||
q15_t* p = inBuffer;
|
for (uint8_t i = 0U; i < 4U; i++, c <<= 2) {
|
||||||
for (uint8_t i = 0U; i < 4U; i++, c <<= 2, p += DMR_RADIO_SYMBOL_LENGTH) {
|
|
||||||
switch (c & MASK) {
|
switch (c & MASK) {
|
||||||
case 0xC0U:
|
case 0xC0U:
|
||||||
::memcpy(p, DMR_LEVELA, DMR_RADIO_SYMBOL_LENGTH * sizeof(q15_t));
|
inBuffer[i] = DMR_LEVELA;
|
||||||
break;
|
break;
|
||||||
case 0x80U:
|
case 0x80U:
|
||||||
::memcpy(p, DMR_LEVELB, DMR_RADIO_SYMBOL_LENGTH * sizeof(q15_t));
|
inBuffer[i] = DMR_LEVELB;
|
||||||
break;
|
break;
|
||||||
case 0x00U:
|
case 0x00U:
|
||||||
::memcpy(p, DMR_LEVELC, DMR_RADIO_SYMBOL_LENGTH * sizeof(q15_t));
|
inBuffer[i] = DMR_LEVELC;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
::memcpy(p, DMR_LEVELD, DMR_RADIO_SYMBOL_LENGTH * sizeof(q15_t));
|
inBuffer[i] = DMR_LEVELD;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t blockSize = DMR_RADIO_SYMBOL_LENGTH * 4U;
|
uint8_t controlBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U];
|
||||||
|
|
||||||
uint8_t controlBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U + 1U];
|
|
||||||
::memset(controlBuffer, MARK_NONE, DMR_RADIO_SYMBOL_LENGTH * 4U * sizeof(uint8_t));
|
::memset(controlBuffer, MARK_NONE, DMR_RADIO_SYMBOL_LENGTH * 4U * sizeof(uint8_t));
|
||||||
controlBuffer[DMR_RADIO_SYMBOL_LENGTH * 2U] = control;
|
controlBuffer[DMR_RADIO_SYMBOL_LENGTH * 2U] = control;
|
||||||
|
|
||||||
// Handle the case of the oscillator not being accurate enough
|
::arm_fir_interpolate_q15(&m_modFilter, inBuffer, outBuffer, 4U);
|
||||||
if (m_sampleCount > 0U) {
|
|
||||||
m_count += DMR_RADIO_SYMBOL_LENGTH * 4U;
|
|
||||||
|
|
||||||
if (m_count >= m_sampleCount) {
|
io.write(STATE_DMR, outBuffer, DMR_RADIO_SYMBOL_LENGTH * 4U, controlBuffer);
|
||||||
if (m_sampleInsert) {
|
|
||||||
inBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U] = inBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U - 1U];
|
|
||||||
for (int8_t i = DMR_RADIO_SYMBOL_LENGTH * 4U - 1; i >= 0; i--)
|
|
||||||
controlBuffer[i + 1] = controlBuffer[i];
|
|
||||||
blockSize++;
|
|
||||||
} else {
|
|
||||||
controlBuffer[DMR_RADIO_SYMBOL_LENGTH * 2U - 1U] = control;
|
|
||||||
for (uint8_t i = 0U; i < (DMR_RADIO_SYMBOL_LENGTH * 4U - 1U); i++)
|
|
||||||
controlBuffer[i] = controlBuffer[i + 1U];
|
|
||||||
blockSize--;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_count -= m_sampleCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::arm_fir_fast_q15(&m_modFilter, inBuffer, outBuffer, blockSize);
|
|
||||||
|
|
||||||
io.write(STATE_DMR, outBuffer, blockSize, controlBuffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t CDMRTX::getSpace1() const
|
uint8_t CDMRTX::getSpace1() const
|
||||||
{
|
{
|
||||||
return m_fifo[0U].getSpace() / (DMR_FRAME_LENGTH_BYTES + 2U);
|
return m_fifo[0U].getSpace() / (DMR_FRAME_LENGTH_BYTES + 2U);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t CDMRTX::getSpace2() const
|
uint8_t CDMRTX::getSpace2() const
|
||||||
{
|
{
|
||||||
return m_fifo[1U].getSpace() / (DMR_FRAME_LENGTH_BYTES + 2U);
|
return m_fifo[1U].getSpace() / (DMR_FRAME_LENGTH_BYTES + 2U);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDMRTX::createData(uint8_t slotIndex)
|
void CDMRTX::createData(uint8_t slotIndex)
|
||||||
{
|
{
|
||||||
if (m_fifo[slotIndex].getData()> 0U) {
|
if (m_fifo[slotIndex].getData() >= DMR_FRAME_LENGTH_BYTES && m_frameCount >= STARTUP_COUNT && m_abortCount[slotIndex] >= ABORT_COUNT) {
|
||||||
for (unsigned int i = 0U; i < DMR_FRAME_LENGTH_BYTES; i++) {
|
for (unsigned int i = 0U; i < DMR_FRAME_LENGTH_BYTES; i++) {
|
||||||
m_poBuffer[i] = m_fifo[slotIndex].get();
|
m_poBuffer[i] = m_fifo[slotIndex].get();
|
||||||
m_markBuffer[i] = MARK_NONE;
|
m_markBuffer[i] = MARK_NONE;
|
||||||
@@ -333,17 +317,42 @@ void CDMRTX::createData(uint8_t slotIndex)
|
|||||||
|
|
||||||
void CDMRTX::createCal()
|
void CDMRTX::createCal()
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0U; i < DMR_FRAME_LENGTH_BYTES; i++) {
|
// 1.2 kHz sine wave generation
|
||||||
m_poBuffer[i] = 0x5FU; // +3, +3, -3, -3 pattern for deviation cal.
|
if (m_modemState == STATE_DMRCAL) {
|
||||||
m_markBuffer[i] = MARK_NONE;
|
for (unsigned int i = 0U; i < DMR_FRAME_LENGTH_BYTES; i++) {
|
||||||
|
m_poBuffer[i] = 0x5FU; // +3, +3, -3, -3 pattern for deviation cal.
|
||||||
|
m_markBuffer[i] = MARK_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_poLen = DMR_FRAME_LENGTH_BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 80 Hz square wave generation
|
||||||
|
if (m_modemState == STATE_LFCAL) {
|
||||||
|
for (unsigned int i = 0U; i < 7U; i++) {
|
||||||
|
m_poBuffer[i] = 0x55U; // +3, +3, ... pattern
|
||||||
|
m_markBuffer[i] = MARK_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_poBuffer[7U] = 0x5FU; // +3, +3, -3, -3 pattern
|
||||||
|
|
||||||
|
for (unsigned int i = 8U; i < 15U; i++) {
|
||||||
|
m_poBuffer[i] = 0xFFU; // -3, -3, ... pattern
|
||||||
|
m_markBuffer[i] = MARK_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_poLen = 15U;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_poLen = DMR_FRAME_LENGTH_BYTES;
|
|
||||||
m_poPtr = 0U;
|
m_poPtr = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDMRTX::createCACH(uint8_t txSlotIndex, uint8_t rxSlotIndex)
|
void CDMRTX::createCACH(uint8_t txSlotIndex, uint8_t rxSlotIndex)
|
||||||
{
|
{
|
||||||
|
m_frameCount++;
|
||||||
|
m_abortCount[0U]++;
|
||||||
|
m_abortCount[1U]++;
|
||||||
|
|
||||||
if (m_cachPtr >= 12U)
|
if (m_cachPtr >= 12U)
|
||||||
m_cachPtr = 0U;
|
m_cachPtr = 0U;
|
||||||
|
|
||||||
@@ -359,7 +368,9 @@ void CDMRTX::createCACH(uint8_t txSlotIndex, uint8_t rxSlotIndex)
|
|||||||
m_markBuffer[1U] = MARK_NONE;
|
m_markBuffer[1U] = MARK_NONE;
|
||||||
m_markBuffer[2U] = rxSlotIndex == 1U ? MARK_SLOT1 : MARK_SLOT2;
|
m_markBuffer[2U] = rxSlotIndex == 1U ? MARK_SLOT1 : MARK_SLOT2;
|
||||||
|
|
||||||
bool at = m_fifo[rxSlotIndex].getData() > 0U;
|
bool at = false;
|
||||||
|
if (m_frameCount >= STARTUP_COUNT)
|
||||||
|
at = m_fifo[rxSlotIndex].getData() > 0U;
|
||||||
bool tc = txSlotIndex == 1U;
|
bool tc = txSlotIndex == 1U;
|
||||||
bool ls0 = true; // For 1 and 2
|
bool ls0 = true; // For 1 and 2
|
||||||
bool ls1 = true;
|
bool ls1 = true;
|
||||||
@@ -395,3 +406,17 @@ void CDMRTX::setColorCode(uint8_t colorCode)
|
|||||||
slotType.encode(colorCode, DT_IDLE, m_idle);
|
slotType.encode(colorCode, DT_IDLE, m_idle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CDMRTX::resetFifo1()
|
||||||
|
{
|
||||||
|
m_fifo[0U].reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDMRTX::resetFifo2()
|
||||||
|
{
|
||||||
|
m_fifo[1U].reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t CDMRTX::getFrameCount()
|
||||||
|
{
|
||||||
|
return m_frameCount;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
|
||||||
* Copyright (C) 2016 by Colin Durbridge G4EML
|
* Copyright (C) 2016 by Colin Durbridge G4EML
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@@ -49,26 +49,31 @@ public:
|
|||||||
|
|
||||||
void process();
|
void process();
|
||||||
|
|
||||||
uint16_t getSpace1() const;
|
void resetFifo1();
|
||||||
uint16_t getSpace2() const;
|
void resetFifo2();
|
||||||
|
uint32_t getFrameCount();
|
||||||
|
|
||||||
|
uint8_t getSpace1() const;
|
||||||
|
uint8_t getSpace2() const;
|
||||||
|
|
||||||
void setColorCode(uint8_t colorCode);
|
void setColorCode(uint8_t colorCode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CSerialRB m_fifo[2U];
|
CSerialRB m_fifo[2U];
|
||||||
arm_fir_instance_q15 m_modFilter;
|
arm_fir_interpolate_instance_q15 m_modFilter;
|
||||||
q15_t m_modState[70U]; // NoTaps + BlockSize - 1, 42 + 20 - 1 plus some spare
|
q15_t m_modState[16U]; // blockSize + phaseLength - 1, 4 + 9 - 1 plus some spare
|
||||||
DMRTXSTATE m_state;
|
DMRTXSTATE m_state;
|
||||||
uint8_t m_idle[DMR_FRAME_LENGTH_BYTES];
|
uint8_t m_idle[DMR_FRAME_LENGTH_BYTES];
|
||||||
uint8_t m_cachPtr;
|
uint8_t m_cachPtr;
|
||||||
uint8_t m_shortLC[12U];
|
uint8_t m_shortLC[12U];
|
||||||
uint8_t m_newShortLC[12U];
|
uint8_t m_newShortLC[12U];
|
||||||
uint8_t m_markBuffer[40U];
|
uint8_t m_markBuffer[40U];
|
||||||
uint8_t m_poBuffer[40U];
|
uint8_t m_poBuffer[40U];
|
||||||
uint16_t m_poLen;
|
uint16_t m_poLen;
|
||||||
uint16_t m_poPtr;
|
uint16_t m_poPtr;
|
||||||
uint32_t m_count;
|
uint32_t m_frameCount;
|
||||||
bool m_abort[2U];
|
uint32_t m_abortCount[2U];
|
||||||
|
bool m_abort[2U];
|
||||||
|
|
||||||
void createData(uint8_t slotIndex);
|
void createData(uint8_t slotIndex);
|
||||||
void createCACH(uint8_t txSlotIndex, uint8_t rxSlotIndex);
|
void createCACH(uint8_t txSlotIndex, uint8_t rxSlotIndex);
|
||||||
|
|||||||
+37
-17
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2009-2015 by Jonathan Naylor G4KLX
|
* Copyright (C) 2009-2015,2017 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,30 +19,50 @@
|
|||||||
#if !defined(DSTARDEFINES_H)
|
#if !defined(DSTARDEFINES_H)
|
||||||
#define DSTARDEFINES_H
|
#define DSTARDEFINES_H
|
||||||
|
|
||||||
const unsigned int DSTAR_RADIO_BIT_LENGTH = 5U; // At 24 kHz sample rate
|
const unsigned int DSTAR_RADIO_SYMBOL_LENGTH = 10U; // At 48 kHz sample rate
|
||||||
|
|
||||||
const unsigned int DSTAR_HEADER_LENGTH_BYTES = 41U;
|
const unsigned int DSTAR_HEADER_LENGTH_BYTES = 41U;
|
||||||
const unsigned int DSTAR_HEADER_LENGTH_BITS = DSTAR_HEADER_LENGTH_BYTES * 8U;
|
|
||||||
|
|
||||||
const unsigned int DSTAR_FEC_SECTION_LENGTH_BYTES = 83U;
|
const unsigned int DSTAR_FEC_SECTION_LENGTH_BYTES = 83U;
|
||||||
const unsigned int DSTAR_FEC_SECTION_LENGTH_BITS = 660U;
|
const unsigned int DSTAR_FEC_SECTION_LENGTH_SYMBOLS = 660U;
|
||||||
|
const unsigned int DSTAR_FEC_SECTION_LENGTH_SAMPLES = DSTAR_FEC_SECTION_LENGTH_SYMBOLS * DSTAR_RADIO_SYMBOL_LENGTH;
|
||||||
|
|
||||||
const unsigned int DSTAR_DATA_LENGTH_BYTES = 12U;
|
const unsigned int DSTAR_DATA_LENGTH_BYTES = 12U;
|
||||||
const unsigned int DSTAR_DATA_LENGTH_BITS = DSTAR_DATA_LENGTH_BYTES * 8U;
|
const unsigned int DSTAR_DATA_LENGTH_SYMBOLS = DSTAR_DATA_LENGTH_BYTES * 8U;
|
||||||
|
const unsigned int DSTAR_DATA_LENGTH_SAMPLES = DSTAR_DATA_LENGTH_SYMBOLS * DSTAR_RADIO_SYMBOL_LENGTH;
|
||||||
|
|
||||||
const uint8_t DSTAR_EOT_BYTES[] = {0x55, 0x55, 0x55, 0x55, 0xC8, 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
const unsigned int DSTAR_END_SYNC_LENGTH_BYTES = 6U;
|
||||||
const unsigned int DSTAR_EOT_LENGTH_BYTES = 6U;
|
const unsigned int DSTAR_END_SYNC_LENGTH_BITS = DSTAR_END_SYNC_LENGTH_BYTES * 8U;
|
||||||
const unsigned int DSTAR_EOT_LENGTH_BITS = DSTAR_EOT_LENGTH_BYTES * 8U;
|
|
||||||
|
|
||||||
const uint8_t DSTAR_DATA_SYNC_LENGTH_BYTES = 3U;
|
const unsigned int DSTAR_FRAME_SYNC_LENGTH_BYTES = 3U;
|
||||||
const uint8_t DSTAR_DATA_SYNC_LENGTH_BITS = DSTAR_DATA_SYNC_LENGTH_BYTES * 8U;
|
const unsigned int DSTAR_FRAME_SYNC_LENGTH_SYMBOLS = DSTAR_FRAME_SYNC_LENGTH_BYTES * 8U;
|
||||||
|
const unsigned int DSTAR_FRAME_SYNC_LENGTH_SAMPLES = DSTAR_FRAME_SYNC_LENGTH_SYMBOLS * DSTAR_RADIO_SYMBOL_LENGTH;
|
||||||
|
|
||||||
const uint8_t DSTAR_DATA_SYNC_BYTES[] = {0x9E, 0x8D, 0x32, 0x88, 0x26, 0x1A, 0x3F, 0x61, 0xE8, 0x55, 0x2D, 0x16};
|
const unsigned int DSTAR_DATA_SYNC_LENGTH_BYTES = 3U;
|
||||||
|
const unsigned int DSTAR_DATA_SYNC_LENGTH_SYMBOLS = DSTAR_DATA_SYNC_LENGTH_BYTES * 8U;
|
||||||
|
const unsigned int DSTAR_DATA_SYNC_LENGTH_SAMPLES = DSTAR_DATA_SYNC_LENGTH_SYMBOLS * DSTAR_RADIO_SYMBOL_LENGTH;
|
||||||
|
|
||||||
const uint8_t DSTAR_SLOW_DATA_TYPE_TEXT = 0x40U;
|
const uint8_t DSTAR_DATA_SYNC_BYTES[] = {0x9E, 0x8D, 0x32, 0x88, 0x26, 0x1A, 0x3F, 0x61, 0xE8, 0x55, 0x2D, 0x16};
|
||||||
const uint8_t DSTAR_SLOW_DATA_TYPE_HEADER = 0x50U;
|
|
||||||
|
|
||||||
const uint8_t DSTAR_SCRAMBLER_BYTES[] = {0x70U, 0x4FU, 0x93U};
|
// D-Star bit order version of 0x55 0x6E 0x0A
|
||||||
|
const uint32_t DSTAR_FRAME_SYNC_DATA = 0x00557650U;
|
||||||
|
const uint32_t DSTAR_FRAME_SYNC_MASK = 0x00FFFFFFU;
|
||||||
|
const bool DSTAR_FRAME_SYNC_SYMBOLS[] = {false, true, false, true, false, true, false, true, false, true, true, true, false, true, true, false, false, true, false, true, false, false, false, false};
|
||||||
|
|
||||||
|
// D-Star bit order version of 0x55 0x2D 0x16
|
||||||
|
const uint32_t DSTAR_DATA_SYNC_DATA = 0x00AAB468U;
|
||||||
|
const uint32_t DSTAR_DATA_SYNC_MASK = 0x00FFFFFFU;
|
||||||
|
const bool DSTAR_DATA_SYNC_SYMBOLS[] = {true, false, true, false, true, false, true, false, true, false, true, true, false, true, false, false, false, true, true, false, true, false, false, false};
|
||||||
|
|
||||||
|
// D-Star bit order version of 0x55 0x55 0xC8 0x7A
|
||||||
|
const uint32_t DSTAR_END_SYNC_DATA = 0xAAAA135EU;
|
||||||
|
const uint32_t DSTAR_END_SYNC_MASK = 0xFFFFFFFFU;
|
||||||
|
const uint8_t DSTAR_END_SYNC_BYTES[] = {0x55, 0x55, 0x55, 0x55, 0xC8, 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
|
||||||
|
const uint8_t DSTAR_SLOW_DATA_TYPE_TEXT = 0x40U;
|
||||||
|
const uint8_t DSTAR_SLOW_DATA_TYPE_HEADER = 0x50U;
|
||||||
|
|
||||||
|
const uint8_t DSTAR_SCRAMBLER_BYTES[] = {0x70U, 0x4FU, 0x93U};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+289
-155
@@ -1,5 +1,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2009-2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2009-2017 by Jonathan Naylor G4KLX
|
||||||
|
* Copyright (C) 2017 by Andy Uribe CA6JAU
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -16,31 +18,17 @@
|
|||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// #define WANT_DEBUG
|
|
||||||
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "DStarRX.h"
|
#include "DStarRX.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
const unsigned int BUFFER_LENGTH = 200U;
|
const unsigned int MAX_FRAMES = 150U;
|
||||||
|
|
||||||
const uint32_t PLLMAX = 0x10000U;
|
|
||||||
const uint32_t PLLINC = PLLMAX / DSTAR_RADIO_BIT_LENGTH;
|
|
||||||
const uint32_t INC = PLLINC / 32U;
|
|
||||||
|
|
||||||
const unsigned int MAX_SYNC_BITS = 50U * DSTAR_DATA_LENGTH_BITS;
|
|
||||||
|
|
||||||
const unsigned int SYNC_POS = 21U * DSTAR_DATA_LENGTH_BITS;
|
|
||||||
const unsigned int SYNC_SCAN_START = SYNC_POS - 3U;
|
|
||||||
const unsigned int SYNC_SCAN_END = SYNC_POS + 3U;
|
|
||||||
|
|
||||||
const q15_t THRESHOLD = 0;
|
|
||||||
|
|
||||||
// D-Star bit order version of 0x55 0x55 0x6E 0x0A
|
// D-Star bit order version of 0x55 0x55 0x6E 0x0A
|
||||||
const uint32_t FRAME_SYNC_DATA = 0x00557650U;
|
const uint32_t FRAME_SYNC_DATA = 0x00557650U;
|
||||||
const uint32_t FRAME_SYNC_MASK = 0x00FFFFFFU;
|
const uint32_t FRAME_SYNC_MASK = 0x00FFFFFFU;
|
||||||
const uint8_t FRAME_SYNC_ERRS = 2U;
|
const uint8_t FRAME_SYNC_ERRS = 1U;
|
||||||
|
|
||||||
// D-Star bit order version of 0x55 0x2D 0x16
|
// D-Star bit order version of 0x55 0x2D 0x16
|
||||||
const uint32_t DATA_SYNC_DATA = 0x00AAB468U;
|
const uint32_t DATA_SYNC_DATA = 0x00AAB468U;
|
||||||
@@ -50,7 +38,7 @@ const uint8_t DATA_SYNC_ERRS = 2U;
|
|||||||
// D-Star bit order version of 0x55 0x55 0xC8 0x7A
|
// D-Star bit order version of 0x55 0x55 0xC8 0x7A
|
||||||
const uint32_t END_SYNC_DATA = 0xAAAA135EU;
|
const uint32_t END_SYNC_DATA = 0xAAAA135EU;
|
||||||
const uint32_t END_SYNC_MASK = 0xFFFFFFFFU;
|
const uint32_t END_SYNC_MASK = 0xFFFFFFFFU;
|
||||||
const uint8_t END_SYNC_ERRS = 3U;
|
const uint8_t END_SYNC_ERRS = 1U;
|
||||||
|
|
||||||
const uint8_t BIT_MASK_TABLE0[] = {0x7FU, 0xBFU, 0xDFU, 0xEFU, 0xF7U, 0xFBU, 0xFDU, 0xFEU};
|
const uint8_t BIT_MASK_TABLE0[] = {0x7FU, 0xBFU, 0xDFU, 0xEFU, 0xF7U, 0xFBU, 0xFDU, 0xFEU};
|
||||||
const uint8_t BIT_MASK_TABLE1[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
const uint8_t BIT_MASK_TABLE1[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
||||||
@@ -244,14 +232,24 @@ const uint16_t CCITT_TABLE[] = {
|
|||||||
0xf78fU, 0xe606U, 0xd49dU, 0xc514U, 0xb1abU, 0xa022U, 0x92b9U, 0x8330U,
|
0xf78fU, 0xe606U, 0xd49dU, 0xc514U, 0xb1abU, 0xa022U, 0x92b9U, 0x8330U,
|
||||||
0x7bc7U, 0x6a4eU, 0x58d5U, 0x495cU, 0x3de3U, 0x2c6aU, 0x1ef1U, 0x0f78U};
|
0x7bc7U, 0x6a4eU, 0x58d5U, 0x495cU, 0x3de3U, 0x2c6aU, 0x1ef1U, 0x0f78U};
|
||||||
|
|
||||||
|
const uint16_t NOENDPTR = 9999U;
|
||||||
|
|
||||||
CDStarRX::CDStarRX() :
|
CDStarRX::CDStarRX() :
|
||||||
m_pll(0U),
|
|
||||||
m_prev(false),
|
|
||||||
m_rxState(DSRXS_NONE),
|
m_rxState(DSRXS_NONE),
|
||||||
m_patternBuffer(0x00U),
|
m_bitBuffer(),
|
||||||
m_rxBuffer(),
|
m_headerBuffer(),
|
||||||
m_rxBufferBits(0U),
|
m_dataBuffer(),
|
||||||
m_dataBits(0U),
|
m_bitPtr(0U),
|
||||||
|
m_headerPtr(0U),
|
||||||
|
m_dataPtr(0U),
|
||||||
|
m_startPtr(NOENDPTR),
|
||||||
|
m_syncPtr(NOENDPTR),
|
||||||
|
m_minSyncPtr(NOENDPTR),
|
||||||
|
m_maxSyncPtr(NOENDPTR),
|
||||||
|
m_maxFrameCorr(0),
|
||||||
|
m_maxDataCorr(0),
|
||||||
|
m_frameCount(0U),
|
||||||
|
m_countdown(0U),
|
||||||
m_mar(0U),
|
m_mar(0U),
|
||||||
m_pathMetric(),
|
m_pathMetric(),
|
||||||
m_pathMemory0(),
|
m_pathMemory0(),
|
||||||
@@ -259,142 +257,146 @@ m_pathMemory1(),
|
|||||||
m_pathMemory2(),
|
m_pathMemory2(),
|
||||||
m_pathMemory3(),
|
m_pathMemory3(),
|
||||||
m_fecOutput(),
|
m_fecOutput(),
|
||||||
m_samples(),
|
m_rssiAccum(0U),
|
||||||
m_samplesPtr(0U)
|
m_rssiCount(0U)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDStarRX::reset()
|
void CDStarRX::reset()
|
||||||
{
|
{
|
||||||
m_pll = 0U;
|
m_rxState = DSRXS_NONE;
|
||||||
m_prev = false;
|
m_headerPtr = 0U;
|
||||||
m_rxState = DSRXS_NONE;
|
m_dataPtr = 0U;
|
||||||
m_patternBuffer = 0x00U;
|
m_bitPtr = 0U;
|
||||||
m_rxBufferBits = 0U;
|
m_maxFrameCorr = 0;
|
||||||
m_dataBits = 0U;
|
m_maxDataCorr = 0;
|
||||||
m_samplesPtr = 0U;
|
m_startPtr = NOENDPTR;
|
||||||
|
m_syncPtr = NOENDPTR;
|
||||||
|
m_minSyncPtr = NOENDPTR;
|
||||||
|
m_maxSyncPtr = NOENDPTR;
|
||||||
|
m_frameCount = 0U;
|
||||||
|
m_countdown = 0U;
|
||||||
|
m_rssiAccum = 0U;
|
||||||
|
m_rssiCount = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDStarRX::samples(const q15_t* samples, uint8_t length)
|
void CDStarRX::samples(const q15_t* samples, const uint16_t* rssi, uint8_t length)
|
||||||
{
|
{
|
||||||
for (uint16_t i = 0U; i < length; i++) {
|
for (uint16_t i = 0U; i < length; i++) {
|
||||||
m_samples[m_samplesPtr] = samples[i];
|
m_rssiAccum += rssi[i];
|
||||||
|
m_rssiCount++;
|
||||||
|
|
||||||
bool bit = samples[i] < THRESHOLD;
|
q15_t sample = samples[i];
|
||||||
|
|
||||||
if (bit != m_prev) {
|
m_bitBuffer[m_bitPtr] <<= 1;
|
||||||
if (m_pll < (PLLMAX / 2U))
|
if (sample < 0)
|
||||||
m_pll += INC;
|
m_bitBuffer[m_bitPtr] |= 0x01U;
|
||||||
else
|
|
||||||
m_pll -= INC;
|
m_dataBuffer[m_dataPtr] = sample;
|
||||||
|
|
||||||
|
switch (m_rxState) {
|
||||||
|
case DSRXS_HEADER:
|
||||||
|
processHeader(sample);
|
||||||
|
break;
|
||||||
|
case DSRXS_DATA:
|
||||||
|
processData();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
processNone(sample);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_prev = bit;
|
m_dataPtr++;
|
||||||
|
if (m_dataPtr >= DSTAR_DATA_LENGTH_SAMPLES)
|
||||||
|
m_dataPtr = 0U;
|
||||||
|
|
||||||
m_pll += PLLINC;
|
m_bitPtr++;
|
||||||
|
if (m_bitPtr >= DSTAR_RADIO_SYMBOL_LENGTH)
|
||||||
if (m_pll >= PLLMAX) {
|
m_bitPtr = 0U;
|
||||||
m_pll -= PLLMAX;
|
|
||||||
|
|
||||||
switch (m_rxState) {
|
|
||||||
case DSRXS_NONE:
|
|
||||||
processNone(bit);
|
|
||||||
break;
|
|
||||||
case DSRXS_HEADER:
|
|
||||||
processHeader(bit);
|
|
||||||
break;
|
|
||||||
case DSRXS_DATA:
|
|
||||||
processData(bit);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_samplesPtr++;
|
|
||||||
if (m_samplesPtr >= DSTAR_DATA_SYNC_LENGTH_BITS)
|
|
||||||
m_samplesPtr = 0U;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDStarRX::processNone(bool bit)
|
void CDStarRX::processNone(q15_t sample)
|
||||||
{
|
{
|
||||||
m_patternBuffer <<= 1;
|
|
||||||
if (bit)
|
|
||||||
m_patternBuffer |= 0x01U;
|
|
||||||
|
|
||||||
// Fuzzy matching of the frame sync sequence
|
// Fuzzy matching of the frame sync sequence
|
||||||
if (countBits32((m_patternBuffer & FRAME_SYNC_MASK) ^ FRAME_SYNC_DATA) <= FRAME_SYNC_ERRS) {
|
bool ret = correlateFrameSync();
|
||||||
DEBUG1("DStarRX: found frame sync in None");
|
if (ret) {
|
||||||
|
m_countdown = 5U;
|
||||||
|
|
||||||
::memset(m_rxBuffer, 0x00U, DSTAR_FEC_SECTION_LENGTH_BYTES);
|
m_headerBuffer[m_headerPtr] = sample;
|
||||||
m_rxBufferBits = 0U;
|
m_headerPtr++;
|
||||||
|
|
||||||
|
m_rssiAccum = 0U;
|
||||||
|
m_rssiCount = 0U;
|
||||||
|
|
||||||
m_rxState = DSRXS_HEADER;
|
m_rxState = DSRXS_HEADER;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exact matching of the data sync bit sequence
|
// Fuzzy matching of the data sync bit sequence
|
||||||
if (countBits32((m_patternBuffer & DATA_SYNC_MASK) ^ DATA_SYNC_DATA) == 0U) {
|
ret = correlateDataSync();
|
||||||
|
if (ret) {
|
||||||
DEBUG1("DStarRX: found data sync in None");
|
DEBUG1("DStarRX: found data sync in None");
|
||||||
|
|
||||||
io.setDecode(true);
|
io.setDecode(true);
|
||||||
io.setADCDetection(true);
|
io.setADCDetection(true);
|
||||||
|
|
||||||
serial.writeDStarData(DSTAR_DATA_SYNC_BYTES, DSTAR_DATA_LENGTH_BYTES);
|
m_rxState = DSRXS_DATA;
|
||||||
|
|
||||||
::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES + 2U);
|
|
||||||
m_rxBufferBits = 0U;
|
|
||||||
|
|
||||||
m_dataBits = 0U;
|
|
||||||
m_rxState = DSRXS_DATA;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDStarRX::processHeader(bool bit)
|
void CDStarRX::processHeader(q15_t sample)
|
||||||
{
|
{
|
||||||
m_patternBuffer <<= 1;
|
if (m_countdown > 0U) {
|
||||||
if (bit)
|
correlateFrameSync();
|
||||||
m_patternBuffer |= 0x01U;
|
m_countdown--;
|
||||||
|
}
|
||||||
|
|
||||||
WRITE_BIT2(m_rxBuffer, m_rxBufferBits, bit);
|
m_headerBuffer[m_headerPtr] = sample;
|
||||||
m_rxBufferBits++;
|
m_headerPtr++;
|
||||||
|
|
||||||
// A full FEC header
|
// A full FEC header
|
||||||
if (m_rxBufferBits == DSTAR_FEC_SECTION_LENGTH_BITS) {
|
if (m_headerPtr == (DSTAR_FEC_SECTION_LENGTH_SAMPLES + DSTAR_RADIO_SYMBOL_LENGTH)) {
|
||||||
// Process the scrambling, interleaving and FEC, then return if the chcksum was correct
|
uint8_t buffer[DSTAR_FEC_SECTION_LENGTH_BYTES];
|
||||||
unsigned char header[DSTAR_HEADER_LENGTH_BYTES];
|
samplesToBits(m_headerBuffer, DSTAR_RADIO_SYMBOL_LENGTH, DSTAR_FEC_SECTION_LENGTH_SYMBOLS, buffer, DSTAR_FEC_SECTION_LENGTH_SAMPLES);
|
||||||
bool ok = rxHeader(m_rxBuffer, header);
|
|
||||||
if (ok) {
|
// Process the scrambling, interleaving and FEC, then return true if the chcksum was correct
|
||||||
|
uint8_t header[DSTAR_HEADER_LENGTH_BYTES];
|
||||||
|
bool ok = rxHeader(buffer, header);
|
||||||
|
if (!ok) {
|
||||||
|
// The checksum failed, return to looking for syncs
|
||||||
|
m_rxState = DSRXS_NONE;
|
||||||
|
m_maxFrameCorr = 0;
|
||||||
|
m_maxDataCorr = 0;
|
||||||
|
} else {
|
||||||
io.setDecode(true);
|
io.setDecode(true);
|
||||||
io.setADCDetection(true);
|
io.setADCDetection(true);
|
||||||
|
|
||||||
serial.writeDStarHeader(header, DSTAR_HEADER_LENGTH_BYTES);
|
writeRSSIHeader(header);
|
||||||
|
|
||||||
::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES + 2U);
|
|
||||||
m_rxBufferBits = 0U;
|
|
||||||
|
|
||||||
m_rxState = DSRXS_DATA;
|
|
||||||
m_dataBits = SYNC_POS - DSTAR_DATA_LENGTH_BITS + 1U;
|
|
||||||
} else {
|
|
||||||
// The checksum failed, return to looking for syncs
|
|
||||||
m_rxState = DSRXS_NONE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ready to start the first data section
|
||||||
|
if (m_headerPtr == (DSTAR_FEC_SECTION_LENGTH_SAMPLES + 2U * DSTAR_RADIO_SYMBOL_LENGTH)) {
|
||||||
|
m_frameCount = 0U;
|
||||||
|
m_dataPtr = 0U;
|
||||||
|
|
||||||
|
m_startPtr = 952U;
|
||||||
|
m_syncPtr = 942U;
|
||||||
|
m_maxSyncPtr = 944U;
|
||||||
|
m_minSyncPtr = 940U;
|
||||||
|
|
||||||
|
DEBUG5("DStarRX: calc start/sync/max/min", m_startPtr, m_syncPtr, m_maxSyncPtr, m_minSyncPtr);
|
||||||
|
|
||||||
|
m_rxState = DSRXS_DATA;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDStarRX::processData(bool bit)
|
void CDStarRX::processData()
|
||||||
{
|
{
|
||||||
m_patternBuffer <<= 1;
|
|
||||||
if (bit)
|
|
||||||
m_patternBuffer |= 0x01U;
|
|
||||||
|
|
||||||
WRITE_BIT2(m_rxBuffer, m_rxBufferBits, bit);
|
|
||||||
m_rxBufferBits++;
|
|
||||||
|
|
||||||
// Fuzzy matching of the end frame sequences
|
// Fuzzy matching of the end frame sequences
|
||||||
if (countBits32((m_patternBuffer & END_SYNC_MASK) ^ END_SYNC_DATA) <= END_SYNC_ERRS) {
|
if (countBits32((m_bitBuffer[m_bitPtr] & DSTAR_END_SYNC_MASK) ^ DSTAR_END_SYNC_DATA) <= END_SYNC_ERRS) {
|
||||||
DEBUG1("DStarRX: Found end sync in Data");
|
DEBUG1("DStarRX: Found end sync in Data");
|
||||||
|
|
||||||
io.setDecode(false);
|
io.setDecode(false);
|
||||||
@@ -402,44 +404,24 @@ void CDStarRX::processData(bool bit)
|
|||||||
|
|
||||||
serial.writeDStarEOT();
|
serial.writeDStarEOT();
|
||||||
|
|
||||||
|
m_maxFrameCorr = 0;
|
||||||
|
m_maxDataCorr = 0;
|
||||||
|
|
||||||
m_rxState = DSRXS_NONE;
|
m_rxState = DSRXS_NONE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fuzzy matching of the data sync bit sequence
|
// Fuzzy matching of the data sync bit sequence
|
||||||
bool syncSeen = false;
|
if (m_minSyncPtr < m_maxSyncPtr) {
|
||||||
if (m_dataBits >= SYNC_SCAN_START && m_dataBits <= (SYNC_POS + 1U)) {
|
if (m_dataPtr >= m_minSyncPtr && m_dataPtr <= m_maxSyncPtr)
|
||||||
if (countBits32((m_patternBuffer & DATA_SYNC_MASK) ^ DATA_SYNC_DATA) <= DATA_SYNC_ERRS) {
|
correlateDataSync();
|
||||||
#if defined(WANT_DEBUG)
|
} else {
|
||||||
if (m_dataBits < SYNC_POS)
|
if (m_dataPtr >= m_minSyncPtr || m_dataPtr <= m_maxSyncPtr)
|
||||||
DEBUG2("DStarRX: found data sync in Data, early", SYNC_POS - m_dataBits);
|
correlateDataSync();
|
||||||
else
|
|
||||||
DEBUG1("DStarRX: found data sync in Data");
|
|
||||||
#endif
|
|
||||||
m_rxBufferBits = DSTAR_DATA_LENGTH_BITS;
|
|
||||||
m_dataBits = 0U;
|
|
||||||
syncSeen = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check to see if the sync is arriving late
|
|
||||||
if (m_dataBits == SYNC_POS) {
|
|
||||||
for (uint8_t i = 1U; i <= 3U; i++) {
|
|
||||||
uint32_t syncMask = DATA_SYNC_MASK >> i;
|
|
||||||
uint32_t syncData = DATA_SYNC_DATA >> i;
|
|
||||||
if (countBits32((m_patternBuffer & syncMask) ^ syncData) <= DATA_SYNC_ERRS) {
|
|
||||||
DEBUG2("DStarRX: found data sync in Data, late", i);
|
|
||||||
m_rxBufferBits -= i;
|
|
||||||
m_dataBits -= i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_dataBits++;
|
|
||||||
|
|
||||||
// We've not seen a data sync for too long, signal RXLOST and change to RX_NONE
|
// We've not seen a data sync for too long, signal RXLOST and change to RX_NONE
|
||||||
if (m_dataBits >= MAX_SYNC_BITS) {
|
if (m_frameCount >= MAX_FRAMES) {
|
||||||
DEBUG1("DStarRX: data sync timed out, lost lock");
|
DEBUG1("DStarRX: data sync timed out, lost lock");
|
||||||
|
|
||||||
io.setDecode(false);
|
io.setDecode(false);
|
||||||
@@ -447,23 +429,176 @@ void CDStarRX::processData(bool bit)
|
|||||||
|
|
||||||
serial.writeDStarLost();
|
serial.writeDStarLost();
|
||||||
|
|
||||||
|
m_maxFrameCorr = 0;
|
||||||
|
m_maxDataCorr = 0;
|
||||||
|
|
||||||
m_rxState = DSRXS_NONE;
|
m_rxState = DSRXS_NONE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send a data frame to the host if the required number of bits have been received, or if a data sync has been seen
|
// Send a data frame to the host if the required number of bits have been received
|
||||||
if (m_rxBufferBits == DSTAR_DATA_LENGTH_BITS) {
|
if (m_dataPtr == m_maxSyncPtr) {
|
||||||
if (syncSeen) {
|
uint8_t buffer[DSTAR_DATA_LENGTH_BYTES + 2U];
|
||||||
m_rxBuffer[9U] = DSTAR_DATA_SYNC_BYTES[9U];
|
samplesToBits(m_dataBuffer, m_startPtr, DSTAR_DATA_LENGTH_SYMBOLS, buffer, DSTAR_DATA_LENGTH_SAMPLES);
|
||||||
m_rxBuffer[10U] = DSTAR_DATA_SYNC_BYTES[10U];
|
|
||||||
m_rxBuffer[11U] = DSTAR_DATA_SYNC_BYTES[11U];
|
if ((m_frameCount % 21U) == 0U) {
|
||||||
|
if (m_frameCount == 0U) {
|
||||||
|
buffer[9U] = DSTAR_DATA_SYNC_BYTES[9U];
|
||||||
|
buffer[10U] = DSTAR_DATA_SYNC_BYTES[10U];
|
||||||
|
buffer[11U] = DSTAR_DATA_SYNC_BYTES[11U];
|
||||||
|
DEBUG5("DStarRX: found start/sync/max/min", m_startPtr, m_syncPtr, m_maxSyncPtr, m_minSyncPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
writeRSSIData(buffer);
|
||||||
|
} else {
|
||||||
|
serial.writeDStarData(buffer, DSTAR_DATA_LENGTH_BYTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
serial.writeDStarData(m_rxBuffer, DSTAR_DATA_LENGTH_BYTES);
|
m_frameCount++;
|
||||||
|
|
||||||
// Start the next frame
|
m_maxFrameCorr = 0;
|
||||||
::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES + 2U);
|
m_maxDataCorr = 0;
|
||||||
m_rxBufferBits = 0U;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDStarRX::writeRSSIHeader(unsigned char* header)
|
||||||
|
{
|
||||||
|
#if defined(SEND_RSSI_DATA)
|
||||||
|
if (m_rssiCount > 0U) {
|
||||||
|
uint16_t rssi = m_rssiAccum / m_rssiCount;
|
||||||
|
|
||||||
|
header[41U] = (rssi >> 8) & 0xFFU;
|
||||||
|
header[42U] = (rssi >> 0) & 0xFFU;
|
||||||
|
|
||||||
|
serial.writeDStarHeader(header, DSTAR_HEADER_LENGTH_BYTES + 2U);
|
||||||
|
} else {
|
||||||
|
serial.writeDStarHeader(header, DSTAR_HEADER_LENGTH_BYTES + 0U);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
serial.writeDStarHeader(header, DSTAR_HEADER_LENGTH_BYTES + 0U);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_rssiAccum = 0U;
|
||||||
|
m_rssiCount = 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDStarRX::writeRSSIData(unsigned char* data)
|
||||||
|
{
|
||||||
|
#if defined(SEND_RSSI_DATA)
|
||||||
|
if (m_rssiCount > 0U) {
|
||||||
|
uint16_t rssi = m_rssiAccum / m_rssiCount;
|
||||||
|
|
||||||
|
data[12U] = (rssi >> 8) & 0xFFU;
|
||||||
|
data[13U] = (rssi >> 0) & 0xFFU;
|
||||||
|
|
||||||
|
serial.writeDStarData(data, DSTAR_DATA_LENGTH_BYTES + 2U);
|
||||||
|
} else {
|
||||||
|
serial.writeDStarData(data, DSTAR_DATA_LENGTH_BYTES + 0U);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
serial.writeDStarData(data, DSTAR_DATA_LENGTH_BYTES + 0U);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_rssiAccum = 0U;
|
||||||
|
m_rssiCount = 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDStarRX::correlateFrameSync()
|
||||||
|
{
|
||||||
|
if (countBits32((m_bitBuffer[m_bitPtr] & DSTAR_FRAME_SYNC_MASK) ^ DSTAR_FRAME_SYNC_DATA) <= FRAME_SYNC_ERRS) {
|
||||||
|
uint16_t ptr = m_dataPtr + DSTAR_DATA_LENGTH_SAMPLES - DSTAR_FRAME_SYNC_LENGTH_SAMPLES + DSTAR_RADIO_SYMBOL_LENGTH;
|
||||||
|
if (ptr >= DSTAR_DATA_LENGTH_SAMPLES)
|
||||||
|
ptr -= DSTAR_DATA_LENGTH_SAMPLES;
|
||||||
|
|
||||||
|
q31_t corr = 0;
|
||||||
|
|
||||||
|
for (uint8_t i = 0U; i < DSTAR_FRAME_SYNC_LENGTH_SYMBOLS; i++) {
|
||||||
|
q15_t val = m_dataBuffer[ptr];
|
||||||
|
|
||||||
|
if (DSTAR_FRAME_SYNC_SYMBOLS[i])
|
||||||
|
corr -= val;
|
||||||
|
else
|
||||||
|
corr += val;
|
||||||
|
|
||||||
|
ptr += DSTAR_RADIO_SYMBOL_LENGTH;
|
||||||
|
if (ptr >= DSTAR_DATA_LENGTH_SAMPLES)
|
||||||
|
ptr -= DSTAR_DATA_LENGTH_SAMPLES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (corr > m_maxFrameCorr) {
|
||||||
|
m_maxFrameCorr = corr;
|
||||||
|
m_headerPtr = 0U;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDStarRX::correlateDataSync()
|
||||||
|
{
|
||||||
|
uint8_t maxErrs = 0U;
|
||||||
|
if (m_rxState == DSRXS_DATA)
|
||||||
|
maxErrs = DATA_SYNC_ERRS;
|
||||||
|
|
||||||
|
if (countBits32((m_bitBuffer[m_bitPtr] & DSTAR_DATA_SYNC_MASK) ^ DSTAR_DATA_SYNC_DATA) <= maxErrs) {
|
||||||
|
uint16_t ptr = m_dataPtr + DSTAR_DATA_LENGTH_SAMPLES - DSTAR_DATA_SYNC_LENGTH_SAMPLES + DSTAR_RADIO_SYMBOL_LENGTH;
|
||||||
|
if (ptr >= DSTAR_DATA_LENGTH_SAMPLES)
|
||||||
|
ptr -= DSTAR_DATA_LENGTH_SAMPLES;
|
||||||
|
|
||||||
|
q31_t corr = 0;
|
||||||
|
|
||||||
|
for (uint8_t i = 0U; i < DSTAR_DATA_SYNC_LENGTH_SYMBOLS; i++) {
|
||||||
|
q15_t val = m_dataBuffer[ptr];
|
||||||
|
|
||||||
|
if (DSTAR_DATA_SYNC_SYMBOLS[i])
|
||||||
|
corr -= val;
|
||||||
|
else
|
||||||
|
corr += val;
|
||||||
|
|
||||||
|
ptr += DSTAR_RADIO_SYMBOL_LENGTH;
|
||||||
|
if (ptr >= DSTAR_DATA_LENGTH_SAMPLES)
|
||||||
|
ptr -= DSTAR_DATA_LENGTH_SAMPLES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (corr > m_maxDataCorr) {
|
||||||
|
m_maxDataCorr = corr;
|
||||||
|
m_frameCount = 0U;
|
||||||
|
|
||||||
|
m_syncPtr = m_dataPtr;
|
||||||
|
|
||||||
|
m_startPtr = m_dataPtr + DSTAR_RADIO_SYMBOL_LENGTH;
|
||||||
|
if (m_startPtr >= DSTAR_DATA_LENGTH_SAMPLES)
|
||||||
|
m_startPtr -= DSTAR_DATA_LENGTH_SAMPLES;
|
||||||
|
|
||||||
|
m_maxSyncPtr = m_syncPtr + 1U;
|
||||||
|
if (m_maxSyncPtr >= DSTAR_DATA_LENGTH_SAMPLES)
|
||||||
|
m_maxSyncPtr -= DSTAR_DATA_LENGTH_SAMPLES;
|
||||||
|
|
||||||
|
m_minSyncPtr = m_syncPtr + DSTAR_DATA_LENGTH_SAMPLES - 1U;
|
||||||
|
if (m_minSyncPtr >= DSTAR_DATA_LENGTH_SAMPLES)
|
||||||
|
m_minSyncPtr -= DSTAR_DATA_LENGTH_SAMPLES;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDStarRX::samplesToBits(const q15_t* inBuffer, uint16_t start, uint16_t count, uint8_t* outBuffer, uint16_t limit)
|
||||||
|
{
|
||||||
|
for (uint16_t i = 0U; i < count; i++) {
|
||||||
|
q15_t sample = inBuffer[start];
|
||||||
|
|
||||||
|
if (sample < 0)
|
||||||
|
WRITE_BIT2(outBuffer, i, true);
|
||||||
|
else
|
||||||
|
WRITE_BIT2(outBuffer, i, false);
|
||||||
|
|
||||||
|
start += DSTAR_RADIO_SYMBOL_LENGTH;
|
||||||
|
if (start >= limit)
|
||||||
|
start -= limit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -682,4 +817,3 @@ bool CDStarRX::checksum(const uint8_t* header) const
|
|||||||
|
|
||||||
return crc8[0U] == header[DSTAR_HEADER_LENGTH_BYTES - 2U] && crc8[1U] == header[DSTAR_HEADER_LENGTH_BYTES - 1U];
|
return crc8[0U] == header[DSTAR_HEADER_LENGTH_BYTES - 2U] && crc8[1U] == header[DSTAR_HEADER_LENGTH_BYTES - 1U];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -32,18 +32,26 @@ class CDStarRX {
|
|||||||
public:
|
public:
|
||||||
CDStarRX();
|
CDStarRX();
|
||||||
|
|
||||||
void samples(const q15_t* samples, uint8_t length);
|
void samples(const q15_t* samples, const uint16_t* rssi, uint8_t length);
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t m_pll;
|
|
||||||
bool m_prev;
|
|
||||||
DSRX_STATE m_rxState;
|
DSRX_STATE m_rxState;
|
||||||
uint32_t m_patternBuffer;
|
uint32_t m_bitBuffer[DSTAR_RADIO_SYMBOL_LENGTH];
|
||||||
uint8_t m_rxBuffer[100U];
|
q15_t m_headerBuffer[DSTAR_FEC_SECTION_LENGTH_SAMPLES + 2U * DSTAR_RADIO_SYMBOL_LENGTH];
|
||||||
unsigned int m_rxBufferBits;
|
q15_t m_dataBuffer[DSTAR_DATA_LENGTH_SAMPLES];
|
||||||
unsigned int m_dataBits;
|
uint16_t m_bitPtr;
|
||||||
|
uint16_t m_headerPtr;
|
||||||
|
uint16_t m_dataPtr;
|
||||||
|
uint16_t m_startPtr;
|
||||||
|
uint16_t m_syncPtr;
|
||||||
|
uint16_t m_minSyncPtr;
|
||||||
|
uint16_t m_maxSyncPtr;
|
||||||
|
q31_t m_maxFrameCorr;
|
||||||
|
q31_t m_maxDataCorr;
|
||||||
|
uint16_t m_frameCount;
|
||||||
|
uint8_t m_countdown;
|
||||||
unsigned int m_mar;
|
unsigned int m_mar;
|
||||||
int m_pathMetric[4U];
|
int m_pathMetric[4U];
|
||||||
unsigned int m_pathMemory0[42U];
|
unsigned int m_pathMemory0[42U];
|
||||||
@@ -51,12 +59,17 @@ private:
|
|||||||
unsigned int m_pathMemory2[42U];
|
unsigned int m_pathMemory2[42U];
|
||||||
unsigned int m_pathMemory3[42U];
|
unsigned int m_pathMemory3[42U];
|
||||||
uint8_t m_fecOutput[42U];
|
uint8_t m_fecOutput[42U];
|
||||||
q15_t m_samples[DSTAR_DATA_SYNC_LENGTH_BITS];
|
uint32_t m_rssiAccum;
|
||||||
uint8_t m_samplesPtr;
|
uint16_t m_rssiCount;
|
||||||
|
|
||||||
void processNone(bool bit);
|
void processNone(q15_t sample);
|
||||||
void processHeader(bool bit);
|
void processHeader(q15_t sample);
|
||||||
void processData(bool bit);
|
void processData();
|
||||||
|
bool correlateFrameSync();
|
||||||
|
bool correlateDataSync();
|
||||||
|
void samplesToBits(const q15_t* inBuffer, uint16_t start, uint16_t count, uint8_t* outBuffer, uint16_t limit);
|
||||||
|
void writeRSSIHeader(unsigned char* header);
|
||||||
|
void writeRSSIData(unsigned char* data);
|
||||||
bool rxHeader(uint8_t* in, uint8_t* out);
|
bool rxHeader(uint8_t* in, uint8_t* out);
|
||||||
void acs(int* metric);
|
void acs(int* metric);
|
||||||
void viterbiDecode(int* data);
|
void viterbiDecode(int* data);
|
||||||
|
|||||||
+31
-51
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2009-2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2009-2017 by Jonathan Naylor G4KLX
|
||||||
|
* Copyright (C) 2017 by Andy Uribe CA6JAU
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -16,8 +17,6 @@
|
|||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define WANT_DEBUG
|
|
||||||
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "DStarTX.h"
|
#include "DStarTX.h"
|
||||||
@@ -28,12 +27,14 @@ const uint8_t BIT_SYNC = 0xAAU;
|
|||||||
|
|
||||||
const uint8_t FRAME_SYNC[] = {0xEAU, 0xA6U, 0x00U};
|
const uint8_t FRAME_SYNC[] = {0xEAU, 0xA6U, 0x00U};
|
||||||
|
|
||||||
// Generated using gaussfir(0.5, 4, 5) in MATLAB
|
// Generated using gaussfir(0.35, 1, 10) in MATLAB
|
||||||
static q15_t DSTAR_GMSK_FILTER[] = {8, 104, 760, 3158, 7421, 9866, 7421, 3158, 760, 104, 8, 0};
|
static q15_t GAUSSIAN_0_35_FILTER[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1001, 1942, 3514, 5930,
|
||||||
const uint16_t DSTAR_GMSK_FILTER_LEN = 12U;
|
9333, 13699, 18751, 23938, 28499, 31644, 32767, 31644,
|
||||||
|
28499, 23938, 18751, 13699, 9333, 5930, 3514, 1942, 1001}; // numTaps = 30, L = 10
|
||||||
|
const uint16_t GAUSSIAN_0_35_FILTER_PHASE_LEN = 3U; // phaseLength = numTaps/L
|
||||||
|
|
||||||
const q15_t DSTAR_LEVEL0[] = {-800, -800, -800, -800, -800};
|
const q15_t DSTAR_LEVEL0 = -841;
|
||||||
const q15_t DSTAR_LEVEL1[] = { 800, 800, 800, 800, 800};
|
const q15_t DSTAR_LEVEL1 = 841;
|
||||||
|
|
||||||
const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
||||||
|
|
||||||
@@ -195,14 +196,14 @@ m_modState(),
|
|||||||
m_poBuffer(),
|
m_poBuffer(),
|
||||||
m_poLen(0U),
|
m_poLen(0U),
|
||||||
m_poPtr(0U),
|
m_poPtr(0U),
|
||||||
m_txDelay(60U), // 100ms
|
m_txDelay(60U) // 100ms
|
||||||
m_count(0U)
|
|
||||||
{
|
{
|
||||||
::memset(m_modState, 0x00U, 60U * sizeof(q15_t));
|
::memset(m_modState, 0x00U, 15U * sizeof(q15_t));
|
||||||
|
|
||||||
m_modFilter.numTaps = DSTAR_GMSK_FILTER_LEN;
|
m_modFilter.L = DSTAR_RADIO_SYMBOL_LENGTH;
|
||||||
m_modFilter.pState = m_modState;
|
m_modFilter.phaseLength = GAUSSIAN_0_35_FILTER_PHASE_LEN;
|
||||||
m_modFilter.pCoeffs = DSTAR_GMSK_FILTER;
|
m_modFilter.pCoeffs = GAUSSIAN_0_35_FILTER;
|
||||||
|
m_modFilter.pState = m_modState;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDStarTX::process()
|
void CDStarTX::process()
|
||||||
@@ -214,8 +215,6 @@ void CDStarTX::process()
|
|||||||
|
|
||||||
if (type == DSTAR_HEADER && m_poLen == 0U) {
|
if (type == DSTAR_HEADER && m_poLen == 0U) {
|
||||||
if (!m_tx) {
|
if (!m_tx) {
|
||||||
m_count = 0U;
|
|
||||||
|
|
||||||
for (uint16_t i = 0U; i < m_txDelay; i++)
|
for (uint16_t i = 0U; i < m_txDelay; i++)
|
||||||
m_poBuffer[m_poLen++] = BIT_SYNC;
|
m_poBuffer[m_poLen++] = BIT_SYNC;
|
||||||
} else {
|
} else {
|
||||||
@@ -241,9 +240,6 @@ void CDStarTX::process()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type == DSTAR_DATA && m_poLen == 0U) {
|
if (type == DSTAR_DATA && m_poLen == 0U) {
|
||||||
if (!m_tx)
|
|
||||||
m_count = 0U;
|
|
||||||
|
|
||||||
// Pop the type byte off
|
// Pop the type byte off
|
||||||
m_buffer.get();
|
m_buffer.get();
|
||||||
|
|
||||||
@@ -258,8 +254,8 @@ void CDStarTX::process()
|
|||||||
m_buffer.get();
|
m_buffer.get();
|
||||||
|
|
||||||
for (uint8_t j = 0U; j < 3U; j++) {
|
for (uint8_t j = 0U; j < 3U; j++) {
|
||||||
for (uint8_t i = 0U; i < DSTAR_EOT_LENGTH_BYTES; i++)
|
for (uint8_t i = 0U; i < DSTAR_END_SYNC_LENGTH_BYTES; i++)
|
||||||
m_poBuffer[m_poLen++] = DSTAR_EOT_BYTES[i];
|
m_poBuffer[m_poLen++] = DSTAR_END_SYNC_BYTES[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
m_poPtr = 0U;
|
m_poPtr = 0U;
|
||||||
@@ -268,11 +264,11 @@ void CDStarTX::process()
|
|||||||
if (m_poLen > 0U) {
|
if (m_poLen > 0U) {
|
||||||
uint16_t space = io.getSpace();
|
uint16_t space = io.getSpace();
|
||||||
|
|
||||||
while (space > (8U * DSTAR_RADIO_BIT_LENGTH)) {
|
while (space > (8U * DSTAR_RADIO_SYMBOL_LENGTH)) {
|
||||||
uint8_t c = m_poBuffer[m_poPtr++];
|
uint8_t c = m_poBuffer[m_poPtr++];
|
||||||
writeByte(c);
|
writeByte(c);
|
||||||
|
|
||||||
space -= 8U * DSTAR_RADIO_BIT_LENGTH;
|
space -= 8U * DSTAR_RADIO_SYMBOL_LENGTH;
|
||||||
|
|
||||||
if (m_poPtr >= m_poLen) {
|
if (m_poPtr >= m_poLen) {
|
||||||
m_poPtr = 0U;
|
m_poPtr = 0U;
|
||||||
@@ -417,50 +413,34 @@ void CDStarTX::txHeader(const uint8_t* in, uint8_t* out) const
|
|||||||
|
|
||||||
void CDStarTX::writeByte(uint8_t c)
|
void CDStarTX::writeByte(uint8_t c)
|
||||||
{
|
{
|
||||||
q15_t inBuffer[DSTAR_RADIO_BIT_LENGTH * 8U + 1U];
|
q15_t inBuffer[8U];
|
||||||
q15_t outBuffer[DSTAR_RADIO_BIT_LENGTH * 8U + 1U];
|
q15_t outBuffer[DSTAR_RADIO_SYMBOL_LENGTH * 8U];
|
||||||
|
|
||||||
uint8_t mask = 0x01U;
|
uint8_t mask = 0x01U;
|
||||||
|
|
||||||
q15_t* p = inBuffer;
|
for (uint8_t i = 0U; i < 8U; i++) {
|
||||||
for (uint8_t i = 0U; i < 8U; i++, p += DSTAR_RADIO_BIT_LENGTH) {
|
|
||||||
if ((c & mask) == mask)
|
if ((c & mask) == mask)
|
||||||
::memcpy(p, DSTAR_LEVEL0, DSTAR_RADIO_BIT_LENGTH * sizeof(q15_t));
|
inBuffer[i] = DSTAR_LEVEL0;
|
||||||
else
|
else
|
||||||
::memcpy(p, DSTAR_LEVEL1, DSTAR_RADIO_BIT_LENGTH * sizeof(q15_t));
|
inBuffer[i] = DSTAR_LEVEL1;
|
||||||
|
|
||||||
mask <<= 1;
|
mask <<= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t blockSize = DSTAR_RADIO_BIT_LENGTH * 8U;
|
::arm_fir_interpolate_q15(&m_modFilter, inBuffer, outBuffer, 8U);
|
||||||
|
|
||||||
// Handle the case of the oscillator not being accurate enough
|
io.write(STATE_DSTAR, outBuffer, DSTAR_RADIO_SYMBOL_LENGTH * 8U);
|
||||||
if (m_sampleCount > 0U) {
|
|
||||||
m_count += DSTAR_RADIO_BIT_LENGTH * 8U;
|
|
||||||
|
|
||||||
if (m_count >= m_sampleCount) {
|
|
||||||
if (m_sampleInsert) {
|
|
||||||
inBuffer[DSTAR_RADIO_BIT_LENGTH * 8U] = inBuffer[DSTAR_RADIO_BIT_LENGTH * 8U - 1U];
|
|
||||||
blockSize++;
|
|
||||||
} else {
|
|
||||||
blockSize--;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_count -= m_sampleCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::arm_fir_fast_q15(&m_modFilter, inBuffer, outBuffer, blockSize);
|
|
||||||
|
|
||||||
io.write(STATE_DSTAR, outBuffer, blockSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDStarTX::setTXDelay(uint8_t delay)
|
void CDStarTX::setTXDelay(uint8_t delay)
|
||||||
{
|
{
|
||||||
m_txDelay = 150U + uint16_t(delay) * 6U; // 250ms + tx delay
|
m_txDelay = 300U + uint16_t(delay) * 6U; // 250ms + tx delay
|
||||||
|
|
||||||
|
if (m_txDelay > 600U)
|
||||||
|
m_txDelay = 600U;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t CDStarTX::getSpace() const
|
uint8_t CDStarTX::getSpace() const
|
||||||
{
|
{
|
||||||
return m_buffer.getSpace() / (DSTAR_DATA_LENGTH_BYTES + 1U);
|
return m_buffer.getSpace() / (DSTAR_DATA_LENGTH_BYTES + 1U);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -35,17 +35,16 @@ public:
|
|||||||
|
|
||||||
void setTXDelay(uint8_t delay);
|
void setTXDelay(uint8_t delay);
|
||||||
|
|
||||||
uint16_t getSpace() const;
|
uint8_t getSpace() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CSerialRB m_buffer;
|
CSerialRB m_buffer;
|
||||||
arm_fir_instance_q15 m_modFilter;
|
arm_fir_interpolate_instance_q15 m_modFilter;
|
||||||
q15_t m_modState[60U]; // NoTaps + BlockSize - 1, 12 + 40 - 1 plus some spare
|
q15_t m_modState[15U]; // blockSize + phaseLength - 1, 8 + 3 - 1 plus some spare
|
||||||
uint8_t m_poBuffer[500U];
|
uint8_t m_poBuffer[600U];
|
||||||
uint16_t m_poLen;
|
uint16_t m_poLen;
|
||||||
uint16_t m_poPtr;
|
uint16_t m_poPtr;
|
||||||
uint16_t m_txDelay; // In bytes
|
uint16_t m_txDelay; // In bytes
|
||||||
uint32_t m_count;
|
|
||||||
|
|
||||||
void txHeader(const uint8_t* in, uint8_t* out) const;
|
void txHeader(const uint8_t* in, uint8_t* out) const;
|
||||||
void writeByte(uint8_t c);
|
void writeByte(uint8_t c);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -20,9 +20,6 @@
|
|||||||
#define DEBUG_H
|
#define DEBUG_H
|
||||||
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
|
|
||||||
#if defined(WANT_DEBUG)
|
|
||||||
|
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
|
|
||||||
#define DEBUG1(a) serial.writeDebug((a))
|
#define DEBUG1(a) serial.writeDebug((a))
|
||||||
@@ -30,18 +27,6 @@
|
|||||||
#define DEBUG3(a,b,c) serial.writeDebug((a),(b),(c))
|
#define DEBUG3(a,b,c) serial.writeDebug((a),(b),(c))
|
||||||
#define DEBUG4(a,b,c,d) serial.writeDebug((a),(b),(c),(d))
|
#define DEBUG4(a,b,c,d) serial.writeDebug((a),(b),(c),(d))
|
||||||
#define DEBUG5(a,b,c,d,e) serial.writeDebug((a),(b),(c),(d),(e))
|
#define DEBUG5(a,b,c,d,e) serial.writeDebug((a),(b),(c),(d),(e))
|
||||||
#define ASSERT(a) serial.writeAssert((a),#a,__FILE__,__LINE__)
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define DEBUG1(a)
|
|
||||||
#define DEBUG2(a,b)
|
|
||||||
#define DEBUG3(a,b,c)
|
|
||||||
#define DEBUG4(a,b,c,d)
|
|
||||||
#define DEBUG5(a,b,c,d,e)
|
|
||||||
#define ASSERT(a)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
#define GITVERSION "0000000"
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,15 +19,22 @@
|
|||||||
#if !defined(GLOBALS_H)
|
#if !defined(GLOBALS_H)
|
||||||
#define GLOBALS_H
|
#define GLOBALS_H
|
||||||
|
|
||||||
#if defined(STM32F4XX) || defined(STM32F4)
|
#if defined(STM32F4XX)
|
||||||
#include "stm32f4xx.h"
|
#include "stm32f4xx.h"
|
||||||
|
#elif defined(STM32F7XX)
|
||||||
|
#include "stm32f7xx.h"
|
||||||
|
#elif defined(STM32F105xC)
|
||||||
|
#include "stm32f1xx.h"
|
||||||
|
#include "STM32Utils.h"
|
||||||
#else
|
#else
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__SAM3X8E__)
|
#if defined(__SAM3X8E__) || defined(STM32F105xC)
|
||||||
#define ARM_MATH_CM3
|
#define ARM_MATH_CM3
|
||||||
#elif defined(STM32F4XX) || defined(STM32F4) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
|
#elif defined(STM32F7XX)
|
||||||
|
#define ARM_MATH_CM7
|
||||||
|
#elif defined(STM32F4XX) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
|
||||||
#define ARM_MATH_CM4
|
#define ARM_MATH_CM4
|
||||||
#else
|
#else
|
||||||
#error "Unknown processor type"
|
#error "Unknown processor type"
|
||||||
@@ -41,8 +48,16 @@ enum MMDVM_STATE {
|
|||||||
STATE_DMR = 2,
|
STATE_DMR = 2,
|
||||||
STATE_YSF = 3,
|
STATE_YSF = 3,
|
||||||
STATE_P25 = 4,
|
STATE_P25 = 4,
|
||||||
|
STATE_NXDN = 5,
|
||||||
|
STATE_POCSAG = 6,
|
||||||
|
|
||||||
// Dummy states start at 90
|
// Dummy states start at 90
|
||||||
|
STATE_NXDNCAL1K = 91,
|
||||||
|
STATE_DMRDMO1K = 92,
|
||||||
|
STATE_P25CAL1K = 93,
|
||||||
|
STATE_DMRCAL1K = 94,
|
||||||
|
STATE_LFCAL = 95,
|
||||||
|
STATE_RSSICAL = 96,
|
||||||
STATE_CWID = 97,
|
STATE_CWID = 97,
|
||||||
STATE_DMRCAL = 98,
|
STATE_DMRCAL = 98,
|
||||||
STATE_DSTARCAL = 99
|
STATE_DSTARCAL = 99
|
||||||
@@ -60,9 +75,15 @@ enum MMDVM_STATE {
|
|||||||
#include "YSFTX.h"
|
#include "YSFTX.h"
|
||||||
#include "P25RX.h"
|
#include "P25RX.h"
|
||||||
#include "P25TX.h"
|
#include "P25TX.h"
|
||||||
|
#include "NXDNRX.h"
|
||||||
|
#include "NXDNTX.h"
|
||||||
|
#include "POCSAGTX.h"
|
||||||
#include "CalDStarRX.h"
|
#include "CalDStarRX.h"
|
||||||
#include "CalDStarTX.h"
|
#include "CalDStarTX.h"
|
||||||
#include "CalDMR.h"
|
#include "CalDMR.h"
|
||||||
|
#include "CalP25.h"
|
||||||
|
#include "CalNXDN.h"
|
||||||
|
#include "CalRSSI.h"
|
||||||
#include "CWIdTX.h"
|
#include "CWIdTX.h"
|
||||||
#include "Debug.h"
|
#include "Debug.h"
|
||||||
#include "IO.h"
|
#include "IO.h"
|
||||||
@@ -73,8 +94,14 @@ const uint8_t MARK_NONE = 0x00U;
|
|||||||
|
|
||||||
const uint16_t RX_BLOCK_SIZE = 2U;
|
const uint16_t RX_BLOCK_SIZE = 2U;
|
||||||
|
|
||||||
const uint16_t TX_RINGBUFFER_SIZE = 500U;
|
const uint16_t TX_RINGBUFFER_SIZE = 1000U;
|
||||||
const uint16_t RX_RINGBUFFER_SIZE = 600U;
|
const uint16_t RX_RINGBUFFER_SIZE = 1200U;
|
||||||
|
|
||||||
|
#if defined(STM32F105xC) || defined(__MK20DX256__)
|
||||||
|
const uint16_t TX_BUFFER_LEN = 2000U;
|
||||||
|
#else
|
||||||
|
const uint16_t TX_BUFFER_LEN = 4000U;
|
||||||
|
#endif
|
||||||
|
|
||||||
extern MMDVM_STATE m_modemState;
|
extern MMDVM_STATE m_modemState;
|
||||||
|
|
||||||
@@ -82,15 +109,14 @@ extern bool m_dstarEnable;
|
|||||||
extern bool m_dmrEnable;
|
extern bool m_dmrEnable;
|
||||||
extern bool m_ysfEnable;
|
extern bool m_ysfEnable;
|
||||||
extern bool m_p25Enable;
|
extern bool m_p25Enable;
|
||||||
|
extern bool m_nxdnEnable;
|
||||||
|
extern bool m_pocsagEnable;
|
||||||
|
|
||||||
extern bool m_duplex;
|
extern bool m_duplex;
|
||||||
|
|
||||||
extern bool m_tx;
|
extern bool m_tx;
|
||||||
extern bool m_dcd;
|
extern bool m_dcd;
|
||||||
|
|
||||||
extern uint32_t m_sampleCount;
|
|
||||||
extern bool m_sampleInsert;
|
|
||||||
|
|
||||||
extern CSerialPort serial;
|
extern CSerialPort serial;
|
||||||
extern CIO io;
|
extern CIO io;
|
||||||
|
|
||||||
@@ -110,9 +136,17 @@ extern CYSFTX ysfTX;
|
|||||||
extern CP25RX p25RX;
|
extern CP25RX p25RX;
|
||||||
extern CP25TX p25TX;
|
extern CP25TX p25TX;
|
||||||
|
|
||||||
|
extern CNXDNRX nxdnRX;
|
||||||
|
extern CNXDNTX nxdnTX;
|
||||||
|
|
||||||
|
extern CPOCSAGTX pocsagTX;
|
||||||
|
|
||||||
extern CCalDStarRX calDStarRX;
|
extern CCalDStarRX calDStarRX;
|
||||||
extern CCalDStarTX calDStarTX;
|
extern CCalDStarTX calDStarTX;
|
||||||
extern CCalDMR calDMR;
|
extern CCalDMR calDMR;
|
||||||
|
extern CCalP25 calP25;
|
||||||
|
extern CCalNXDN calNXDN;
|
||||||
|
extern CCalRSSI calRSSI;
|
||||||
|
|
||||||
extern CCWIdTX cwIdTX;
|
extern CCWIdTX cwIdTX;
|
||||||
|
|
||||||
|
|||||||
+235
@@ -0,0 +1,235 @@
|
|||||||
|
/*
|
||||||
|
* 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
* 28-4-2017 Created for MMDVM Pi shield for Teensy by Chris Huitema
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
#include "Globals.h"
|
||||||
|
|
||||||
|
#if defined(VK6MST_TEENSY_PI3_SHIELD_I2C)
|
||||||
|
|
||||||
|
#include <i2c_t3.h> //available here https://github.com/nox771/i2c_t3 or maybe the normal wire will work #include <wire.h> justs need to test i guess
|
||||||
|
|
||||||
|
#define I2C_ADDRESS 0x22
|
||||||
|
#define I2C_SPEED 100000
|
||||||
|
|
||||||
|
// Function prototypes
|
||||||
|
void receiveEvent(size_t count);
|
||||||
|
void requestEvent(void);
|
||||||
|
|
||||||
|
#define TX_FIFO_SIZE 512U
|
||||||
|
#define RX_FIFO_SIZE 512U
|
||||||
|
|
||||||
|
volatile uint8_t TXfifo[TX_FIFO_SIZE];
|
||||||
|
volatile uint8_t RXfifo[RX_FIFO_SIZE];
|
||||||
|
volatile uint16_t TXfifohead, TXfifotail;
|
||||||
|
volatile uint16_t RXfifohead, RXfifotail;
|
||||||
|
|
||||||
|
// Init queues
|
||||||
|
void TXfifoinit(void)
|
||||||
|
{
|
||||||
|
TXfifohead = 0U;
|
||||||
|
TXfifotail = 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RXfifoinit()
|
||||||
|
{
|
||||||
|
RXfifohead = 0U;
|
||||||
|
RXfifotail = 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
// How full is queue
|
||||||
|
|
||||||
|
uint16_t TXfifolevel(void)
|
||||||
|
{
|
||||||
|
uint32_t tail = TXfifotail;
|
||||||
|
uint32_t head = TXfifohead;
|
||||||
|
|
||||||
|
if (tail > head)
|
||||||
|
return TX_FIFO_SIZE + head - tail;
|
||||||
|
else
|
||||||
|
return head - tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t RXfifolevel(void)
|
||||||
|
{
|
||||||
|
uint32_t tail = RXfifotail;
|
||||||
|
uint32_t head = RXfifohead;
|
||||||
|
|
||||||
|
if (tail > head)
|
||||||
|
return RX_FIFO_SIZE + head - tail;
|
||||||
|
else
|
||||||
|
return head - tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t TXfifoput(uint8_t next)
|
||||||
|
{
|
||||||
|
if (TXfifolevel() < TX_FIFO_SIZE) {
|
||||||
|
TXfifo[TXfifohead] = next;
|
||||||
|
|
||||||
|
TXfifohead++;
|
||||||
|
if (TXfifohead >= TX_FIFO_SIZE)
|
||||||
|
TXfifohead = 0U;
|
||||||
|
return 1U;
|
||||||
|
} else {
|
||||||
|
return 0U; // signal an overflow occurred by returning a zero count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2Cbegin(void)
|
||||||
|
{
|
||||||
|
// Setup for Slave mode, address 0x22, pins 18/19, external pullups, speed in hz
|
||||||
|
Wire.begin(I2C_SLAVE, I2C_ADDRESS, I2C_PINS_18_19, I2C_PULLUP_EXT, I2C_SPEED);
|
||||||
|
|
||||||
|
// register events
|
||||||
|
Wire.onReceive(receiveEvent);
|
||||||
|
Wire.onRequest(requestEvent);
|
||||||
|
|
||||||
|
// initialize the fifos
|
||||||
|
TXfifoinit();
|
||||||
|
RXfifoinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int I2Cavailable(void)
|
||||||
|
{
|
||||||
|
if (RXfifolevel() > 0U)
|
||||||
|
return 1U;
|
||||||
|
else
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t I2Cread(void)
|
||||||
|
{
|
||||||
|
uint8_t data_c = RXfifo[RXfifotail];
|
||||||
|
|
||||||
|
RXfifotail++;
|
||||||
|
if (RXfifotail >= RX_FIFO_SIZE)
|
||||||
|
RXfifotail = 0U;
|
||||||
|
|
||||||
|
return data_c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void I2Cwrite(const uint8_t* data, uint16_t length)
|
||||||
|
{
|
||||||
|
for (uint16_t i = 0U; i < length; i++)
|
||||||
|
TXfifoput(data[i]); //puts it in the fifo
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// handle Rx Event (incoming I2C data)
|
||||||
|
//
|
||||||
|
void receiveEvent(size_t count)
|
||||||
|
{
|
||||||
|
for (uint16_t i = 0U; i < count; i++)
|
||||||
|
{
|
||||||
|
if (RXfifolevel() < RX_FIFO_SIZE) {
|
||||||
|
RXfifo[RXfifohead] = Wire.readByte();
|
||||||
|
if (RXfifo[RXfifohead] != -1){
|
||||||
|
RXfifohead++;
|
||||||
|
if (RXfifohead >= RX_FIFO_SIZE) RXfifohead = 0U;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Wire.readByte(); // drop data if mem full.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// handle Tx Event (outgoing I2C data)
|
||||||
|
//
|
||||||
|
void requestEvent(void)
|
||||||
|
{
|
||||||
|
if (TXfifolevel() > 0) {
|
||||||
|
if (Wire.write(TXfifo[TXfifotail])){ //write to i2c
|
||||||
|
TXfifotail++;
|
||||||
|
if (TXfifotail >= TX_FIFO_SIZE) TXfifotail = 0U;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/************************************/
|
||||||
|
|
||||||
|
void CSerialPort::beginInt(uint8_t n, int speed)
|
||||||
|
{
|
||||||
|
switch (n) {
|
||||||
|
case 1U:
|
||||||
|
return I2Cbegin();
|
||||||
|
case 3U:
|
||||||
|
Serial3.begin(speed);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int CSerialPort::availableInt(uint8_t n)
|
||||||
|
{
|
||||||
|
switch (n) {
|
||||||
|
case 1U:
|
||||||
|
return I2Cavailable();
|
||||||
|
case 3U:
|
||||||
|
return Serial3.available();
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int CSerialPort::availableForWriteInt(uint8_t n)
|
||||||
|
{
|
||||||
|
switch (n) {
|
||||||
|
case 3U:
|
||||||
|
return Serial3.availableForWrite();
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t CSerialPort::readInt(uint8_t n)
|
||||||
|
{
|
||||||
|
switch (n) {
|
||||||
|
case 1U:
|
||||||
|
return I2Cread();
|
||||||
|
case 3U:
|
||||||
|
return Serial3.read();
|
||||||
|
default:
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSerialPort::writeInt(uint8_t n, const uint8_t* data, uint16_t length, bool flush)
|
||||||
|
{
|
||||||
|
switch (n) {
|
||||||
|
case 1U:
|
||||||
|
I2Cwrite(data, length);
|
||||||
|
break;
|
||||||
|
case 3U:
|
||||||
|
Serial3.write(data, length);
|
||||||
|
if (flush)
|
||||||
|
Serial3.flush();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
|
||||||
* Copyright (C) 2015 by Jim Mclaughlin KI6ZUM
|
* Copyright (C) 2015 by Jim Mclaughlin KI6ZUM
|
||||||
* Copyright (C) 2016 by Colin Durbridge G4EML
|
* Copyright (C) 2016 by Colin Durbridge G4EML
|
||||||
*
|
*
|
||||||
@@ -18,28 +18,45 @@
|
|||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// #define WANT_DEBUG
|
|
||||||
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "IO.h"
|
#include "IO.h"
|
||||||
|
|
||||||
#if defined(WIDE_C4FSK_FILTERS_RX)
|
// Generated using [b, a] = butter(1, 0.0005) in MATLAB
|
||||||
// Generated using rcosdesign(0.2, 4, 5, 'sqrt') in MATLAB
|
static q31_t DC_FILTER[] = {1685306, 0, 1685306, 0, 2144113034, 0}; // {b0, 0, b1, b2, -a1, -a2}
|
||||||
static q15_t C4FSK_FILTER[] = {688, -680, -2158, -3060, -2724, -775, 2684, 7041, 11310, 14425, 15565, 14425,
|
const uint32_t DC_FILTER_STAGES = 1U; // One Biquad stage
|
||||||
11310, 7041, 2684, -775, -2724, -3060, -2158, -680, 688, 0};
|
|
||||||
const uint16_t C4FSK_FILTER_LEN = 22U;
|
|
||||||
#else
|
|
||||||
// Generated using rcosdesign(0.2, 8, 5, 'sqrt') in MATLAB
|
|
||||||
static q15_t C4FSK_FILTER[] = {401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995,
|
|
||||||
11237, 14331, 15464, 14331, 11237, 6995, 2667, -770, -2706, -3040, -2144, -675, 683, 1450, 1472, 909, 112,
|
|
||||||
-553, -847, -731, -340, 104, 401, 0};
|
|
||||||
const uint16_t C4FSK_FILTER_LEN = 42U;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Generated using gaussfir(0.5, 4, 5) in MATLAB
|
// Generated using rcosdesign(0.2, 8, 10, 'sqrt') in MATLAB
|
||||||
static q15_t GMSK_FILTER[] = {8, 104, 760, 3158, 7421, 9866, 7421, 3158, 760, 104, 8, 0};
|
static q15_t RRC_0_2_FILTER[] = {284, 198, 73, -78, -240, -393, -517, -590, -599, -533, -391, -181, 79, 364, 643, 880, 1041, 1097, 1026, 819,
|
||||||
const uint16_t GMSK_FILTER_LEN = 12U;
|
483, 39, -477, -1016, -1516, -1915, -2150, -2164, -1914, -1375, -545, 557, 1886, 3376, 4946, 6502, 7946, 9184,
|
||||||
|
10134, 10731, 10935, 10731, 10134, 9184, 7946, 6502, 4946, 3376, 1886, 557, -545, -1375, -1914, -2164, -2150,
|
||||||
|
-1915, -1516, -1016, -477, 39, 483, 819, 1026, 1097, 1041, 880, 643, 364, 79, -181, -391, -533, -599, -590,
|
||||||
|
-517, -393, -240, -78, 73, 198, 284, 0};
|
||||||
|
const uint16_t RRC_0_2_FILTER_LEN = 82U;
|
||||||
|
|
||||||
|
// Generated using rcosdesign(0.2, 8, 20, 'sqrt') in MATLAB
|
||||||
|
static q15_t NXDN_0_2_FILTER[] = {201, 174, 140, 99, 52, 0, -55, -112, -170, -226, -278, -325, -365, -397, -417, -427, -424, -407, -377, -333, -277, -208,
|
||||||
|
-128, -40, 56, 156, 258, 358, 455, 544, 622, 687, 736, 766, 775, 762, 725, 664, 579, 471, 342, 193, 27, -151, -338, -528,
|
||||||
|
-718, -901, -1072, -1225, -1354, -1454, -1520, -1547, -1530, -1466, -1353, -1189, -972, -704, -385, -18, 394, 846, 1333,
|
||||||
|
1850, 2388, 2940, 3498, 4053, 4598, 5122, 5619, 6079, 6494, 6859, 7166, 7410, 7588, 7696, 7732, 7696, 7588, 7410, 7166,
|
||||||
|
6859, 6494, 6079, 5619, 5122, 4598, 4053, 3498, 2940, 2388, 1850, 1333, 846, 394, -18, -385, -704, -972, -1189, -1353,
|
||||||
|
-1466, -1530, -1547, -1520, -1454, -1354, -1225, -1072, -901, -718, -528, -338, -151, 27, 193, 342, 471, 579, 664, 725,
|
||||||
|
762, 775, 766, 736, 687, 622, 544, 455, 358, 258, 156, 56, -40, -128, -208, -277, -333, -377, -407, -424, -427, -417, -397,
|
||||||
|
-365, -325, -278, -226, -170, -112, -55, 0, 52, 99, 140, 174, 201, 0};
|
||||||
|
const uint16_t NXDN_0_2_FILTER_LEN = 162U;
|
||||||
|
|
||||||
|
static q15_t NXDN_ISINC_FILTER[] = {7616, -1333, -1856, -2611, -3399, -4006, -4230, -3918, -2988, -1458, 561, 2867, 5200, 7276, 8832, 9665,
|
||||||
|
9665, 8832, 7276, 5200, 2867, 561, -1458, -2988, -3918, -4230, -4006, -3399, -2611, -1856, -1333, 7616};
|
||||||
|
const uint16_t NXDN_ISINC_FILTER_LEN = 32U;
|
||||||
|
|
||||||
|
#if !defined (DSTARBOXCAR)
|
||||||
|
// Generated using gaussfir(0.5, 4, 10) in MATLAB
|
||||||
|
static q15_t GAUSSIAN_0_5_FILTER[] = {1, 4, 15, 52, 151, 380, 832, 1579, 2599, 3710, 4594, 4933, 4594, 3710, 2599, 1579, 832, 380, 151, 52, 15, 4, 1, 0};
|
||||||
|
const uint16_t GAUSSIAN_0_5_FILTER_LEN = 24U;
|
||||||
|
#endif
|
||||||
|
// One symbol boxcar filter
|
||||||
|
static q15_t BOXCAR_FILTER[] = {6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 0, 0};
|
||||||
|
const uint16_t BOXCAR_FILTER_LEN = 12U;
|
||||||
|
|
||||||
const uint16_t DC_OFFSET = 2048U;
|
const uint16_t DC_OFFSET = 2048U;
|
||||||
|
|
||||||
@@ -48,10 +65,22 @@ m_started(false),
|
|||||||
m_rxBuffer(RX_RINGBUFFER_SIZE),
|
m_rxBuffer(RX_RINGBUFFER_SIZE),
|
||||||
m_txBuffer(TX_RINGBUFFER_SIZE),
|
m_txBuffer(TX_RINGBUFFER_SIZE),
|
||||||
m_rssiBuffer(RX_RINGBUFFER_SIZE),
|
m_rssiBuffer(RX_RINGBUFFER_SIZE),
|
||||||
m_C4FSKFilter(),
|
m_dcFilter(),
|
||||||
m_GMSKFilter(),
|
m_dcState(),
|
||||||
m_C4FSKState(),
|
m_rrcFilter(),
|
||||||
m_GMSKState(),
|
#if !defined (DSTARBOXCAR)
|
||||||
|
m_gaussianFilter(),
|
||||||
|
#endif
|
||||||
|
m_boxcarFilter(),
|
||||||
|
m_nxdnFilter(),
|
||||||
|
m_nxdnISincFilter(),
|
||||||
|
m_rrcState(),
|
||||||
|
#if !defined (DSTARBOXCAR)
|
||||||
|
m_gaussianState(),
|
||||||
|
#endif
|
||||||
|
m_boxcarState(),
|
||||||
|
m_nxdnState(),
|
||||||
|
m_nxdnISincState(),
|
||||||
m_pttInvert(false),
|
m_pttInvert(false),
|
||||||
m_rxLevel(128 * 128),
|
m_rxLevel(128 * 128),
|
||||||
m_cwIdTXLevel(128 * 128),
|
m_cwIdTXLevel(128 * 128),
|
||||||
@@ -59,27 +88,185 @@ m_dstarTXLevel(128 * 128),
|
|||||||
m_dmrTXLevel(128 * 128),
|
m_dmrTXLevel(128 * 128),
|
||||||
m_ysfTXLevel(128 * 128),
|
m_ysfTXLevel(128 * 128),
|
||||||
m_p25TXLevel(128 * 128),
|
m_p25TXLevel(128 * 128),
|
||||||
|
m_nxdnTXLevel(128 * 128),
|
||||||
|
m_pocsagTXLevel(128 * 128),
|
||||||
|
m_rxDCOffset(DC_OFFSET),
|
||||||
|
m_txDCOffset(DC_OFFSET),
|
||||||
m_ledCount(0U),
|
m_ledCount(0U),
|
||||||
m_ledValue(true),
|
m_ledValue(true),
|
||||||
m_detect(false),
|
m_detect(false),
|
||||||
m_adcOverflow(0U),
|
m_adcOverflow(0U),
|
||||||
m_dacOverflow(0U),
|
m_dacOverflow(0U),
|
||||||
m_count(0U),
|
|
||||||
m_watchdog(0U),
|
m_watchdog(0U),
|
||||||
m_lockout(false)
|
m_lockout(false)
|
||||||
{
|
{
|
||||||
::memset(m_C4FSKState, 0x00U, 70U * sizeof(q15_t));
|
::memset(m_rrcState, 0x00U, 140U * sizeof(q15_t));
|
||||||
::memset(m_GMSKState, 0x00U, 40U * sizeof(q15_t));
|
#if !defined (DSTARBOXCAR)
|
||||||
|
::memset(m_gaussianState, 0x00U, 80U * sizeof(q15_t));
|
||||||
|
#endif
|
||||||
|
::memset(m_boxcarState, 0x00U, 60U * sizeof(q15_t));
|
||||||
|
::memset(m_nxdnState, 0x00U, 220U * sizeof(q15_t));
|
||||||
|
::memset(m_nxdnISincState, 0x00U, 60U * sizeof(q15_t));
|
||||||
|
::memset(m_dcState, 0x00U, 4U * sizeof(q31_t));
|
||||||
|
|
||||||
m_C4FSKFilter.numTaps = C4FSK_FILTER_LEN;
|
m_dcFilter.numStages = DC_FILTER_STAGES;
|
||||||
m_C4FSKFilter.pState = m_C4FSKState;
|
m_dcFilter.pState = m_dcState;
|
||||||
m_C4FSKFilter.pCoeffs = C4FSK_FILTER;
|
m_dcFilter.pCoeffs = DC_FILTER;
|
||||||
|
m_dcFilter.postShift = 0;
|
||||||
|
|
||||||
m_GMSKFilter.numTaps = GMSK_FILTER_LEN;
|
m_rrcFilter.numTaps = RRC_0_2_FILTER_LEN;
|
||||||
m_GMSKFilter.pState = m_GMSKState;
|
m_rrcFilter.pState = m_rrcState;
|
||||||
m_GMSKFilter.pCoeffs = GMSK_FILTER;
|
m_rrcFilter.pCoeffs = RRC_0_2_FILTER;
|
||||||
|
#if !defined (DSTARBOXCAR)
|
||||||
|
m_gaussianFilter.numTaps = GAUSSIAN_0_5_FILTER_LEN;
|
||||||
|
m_gaussianFilter.pState = m_gaussianState;
|
||||||
|
m_gaussianFilter.pCoeffs = GAUSSIAN_0_5_FILTER;
|
||||||
|
#endif
|
||||||
|
m_boxcarFilter.numTaps = BOXCAR_FILTER_LEN;
|
||||||
|
m_boxcarFilter.pState = m_boxcarState;
|
||||||
|
m_boxcarFilter.pCoeffs = BOXCAR_FILTER;
|
||||||
|
|
||||||
|
m_nxdnFilter.numTaps = NXDN_0_2_FILTER_LEN;
|
||||||
|
m_nxdnFilter.pState = m_nxdnState;
|
||||||
|
m_nxdnFilter.pCoeffs = NXDN_0_2_FILTER;
|
||||||
|
|
||||||
|
m_nxdnISincFilter.numTaps = NXDN_ISINC_FILTER_LEN;
|
||||||
|
m_nxdnISincFilter.pState = m_nxdnISincState;
|
||||||
|
m_nxdnISincFilter.pCoeffs = NXDN_ISINC_FILTER;
|
||||||
|
|
||||||
initInt();
|
initInt();
|
||||||
|
|
||||||
|
selfTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIO::selfTest()
|
||||||
|
{
|
||||||
|
bool ledValue = false;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < 6; i++) {
|
||||||
|
ledValue = !ledValue;
|
||||||
|
|
||||||
|
// We exclude PTT to avoid trigger the transmitter
|
||||||
|
setLEDInt(ledValue);
|
||||||
|
setCOSInt(ledValue);
|
||||||
|
#if defined(MODE_PINS)
|
||||||
|
setDStarInt(ledValue);
|
||||||
|
setDMRInt(ledValue);
|
||||||
|
setYSFInt(ledValue);
|
||||||
|
setP25Int(ledValue);
|
||||||
|
setNXDNInt(ledValue);
|
||||||
|
setPOCSAGInt(ledValue);
|
||||||
|
#endif
|
||||||
|
delayInt(250);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(MODE_PINS)
|
||||||
|
setDStarInt(true);
|
||||||
|
setDMRInt(false);
|
||||||
|
setYSFInt(false);
|
||||||
|
setP25Int(false);
|
||||||
|
setNXDNInt(false);
|
||||||
|
setPOCSAGInt(false);
|
||||||
|
|
||||||
|
delayInt(250);
|
||||||
|
|
||||||
|
setDStarInt(true);
|
||||||
|
setDMRInt(true);
|
||||||
|
setYSFInt(false);
|
||||||
|
setP25Int(false);
|
||||||
|
setNXDNInt(false);
|
||||||
|
setPOCSAGInt(false);
|
||||||
|
|
||||||
|
delayInt(250);
|
||||||
|
|
||||||
|
setDStarInt(true);
|
||||||
|
setDMRInt(true);
|
||||||
|
setYSFInt(true);
|
||||||
|
setP25Int(false);
|
||||||
|
setNXDNInt(false);
|
||||||
|
setPOCSAGInt(false);
|
||||||
|
|
||||||
|
delayInt(250);
|
||||||
|
|
||||||
|
setDStarInt(true);
|
||||||
|
setDMRInt(true);
|
||||||
|
setYSFInt(true);
|
||||||
|
setP25Int(true);
|
||||||
|
setNXDNInt(false);
|
||||||
|
setPOCSAGInt(false);
|
||||||
|
|
||||||
|
delayInt(250);
|
||||||
|
|
||||||
|
setDStarInt(true);
|
||||||
|
setDMRInt(true);
|
||||||
|
setYSFInt(true);
|
||||||
|
setP25Int(true);
|
||||||
|
setNXDNInt(true);
|
||||||
|
setPOCSAGInt(false);
|
||||||
|
|
||||||
|
delayInt(250);
|
||||||
|
|
||||||
|
setDStarInt(true);
|
||||||
|
setDMRInt(true);
|
||||||
|
setYSFInt(true);
|
||||||
|
setP25Int(true);
|
||||||
|
setNXDNInt(true);
|
||||||
|
setPOCSAGInt(true);
|
||||||
|
|
||||||
|
delayInt(250);
|
||||||
|
|
||||||
|
setDStarInt(true);
|
||||||
|
setDMRInt(true);
|
||||||
|
setYSFInt(true);
|
||||||
|
setP25Int(true);
|
||||||
|
setNXDNInt(true);
|
||||||
|
setPOCSAGInt(false);
|
||||||
|
|
||||||
|
delayInt(250);
|
||||||
|
|
||||||
|
setDStarInt(true);
|
||||||
|
setDMRInt(true);
|
||||||
|
setYSFInt(true);
|
||||||
|
setP25Int(true);
|
||||||
|
setNXDNInt(false);
|
||||||
|
setPOCSAGInt(false);
|
||||||
|
|
||||||
|
delayInt(250);
|
||||||
|
|
||||||
|
setDStarInt(true);
|
||||||
|
setDMRInt(true);
|
||||||
|
setYSFInt(true);
|
||||||
|
setP25Int(false);
|
||||||
|
setNXDNInt(false);
|
||||||
|
setPOCSAGInt(false);
|
||||||
|
|
||||||
|
delayInt(250);
|
||||||
|
|
||||||
|
setDStarInt(true);
|
||||||
|
setDMRInt(true);
|
||||||
|
setYSFInt(false);
|
||||||
|
setP25Int(false);
|
||||||
|
setNXDNInt(false);
|
||||||
|
setPOCSAGInt(false);
|
||||||
|
|
||||||
|
delayInt(250);
|
||||||
|
|
||||||
|
setDStarInt(true);
|
||||||
|
setDMRInt(false);
|
||||||
|
setYSFInt(false);
|
||||||
|
setP25Int(false);
|
||||||
|
setNXDNInt(false);
|
||||||
|
setPOCSAGInt(false);
|
||||||
|
|
||||||
|
delayInt(250);
|
||||||
|
|
||||||
|
setDStarInt(false);
|
||||||
|
setDMRInt(false);
|
||||||
|
setYSFInt(false);
|
||||||
|
setP25Int(false);
|
||||||
|
setNXDNInt(false);
|
||||||
|
setPOCSAGInt(false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void CIO::start()
|
void CIO::start()
|
||||||
@@ -89,7 +276,6 @@ void CIO::start()
|
|||||||
|
|
||||||
startInt();
|
startInt();
|
||||||
|
|
||||||
m_count = 0U;
|
|
||||||
m_started = true;
|
m_started = true;
|
||||||
|
|
||||||
setMode();
|
setMode();
|
||||||
@@ -100,8 +286,8 @@ void CIO::process()
|
|||||||
m_ledCount++;
|
m_ledCount++;
|
||||||
if (m_started) {
|
if (m_started) {
|
||||||
// Two seconds timeout
|
// Two seconds timeout
|
||||||
if (m_watchdog >= 48000U) {
|
if (m_watchdog >= 96000U) {
|
||||||
if (m_modemState == STATE_DSTAR || m_modemState == STATE_DMR || m_modemState == STATE_YSF) {
|
if (m_modemState == STATE_DSTAR || m_modemState == STATE_DMR || m_modemState == STATE_YSF || m_modemState == STATE_P25 || m_modemState == STATE_NXDN) {
|
||||||
if (m_modemState == STATE_DMR && m_tx)
|
if (m_modemState == STATE_DMR && m_tx)
|
||||||
dmrTX.setStart(false);
|
dmrTX.setStart(false);
|
||||||
m_modemState = STATE_IDLE;
|
m_modemState = STATE_IDLE;
|
||||||
@@ -111,13 +297,17 @@ void CIO::process()
|
|||||||
m_watchdog = 0U;
|
m_watchdog = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_ledCount >= 24000U) {
|
#if defined(CONSTANT_SRV_LED)
|
||||||
|
setLEDInt(true);
|
||||||
|
#else
|
||||||
|
if (m_ledCount >= 48000U) {
|
||||||
m_ledCount = 0U;
|
m_ledCount = 0U;
|
||||||
m_ledValue = !m_ledValue;
|
m_ledValue = !m_ledValue;
|
||||||
setLEDInt(m_ledValue);
|
setLEDInt(m_ledValue);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
if (m_ledCount >= 240000U) {
|
if (m_ledCount >= 480000U) {
|
||||||
m_ledCount = 0U;
|
m_ledCount = 0U;
|
||||||
m_ledValue = !m_ledValue;
|
m_ledValue = !m_ledValue;
|
||||||
setLEDInt(m_ledValue);
|
setLEDInt(m_ledValue);
|
||||||
@@ -136,11 +326,9 @@ void CIO::process()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_rxBuffer.getData() >= RX_BLOCK_SIZE) {
|
if (m_rxBuffer.getData() >= RX_BLOCK_SIZE) {
|
||||||
q15_t samples[RX_BLOCK_SIZE + 1U];
|
q15_t samples[RX_BLOCK_SIZE];
|
||||||
uint8_t control[RX_BLOCK_SIZE + 1U];
|
uint8_t control[RX_BLOCK_SIZE];
|
||||||
uint16_t rssi[RX_BLOCK_SIZE + 1U];
|
uint16_t rssi[RX_BLOCK_SIZE];
|
||||||
|
|
||||||
uint8_t blockSize = RX_BLOCK_SIZE;
|
|
||||||
|
|
||||||
for (uint16_t i = 0U; i < RX_BLOCK_SIZE; i++) {
|
for (uint16_t i = 0U; i < RX_BLOCK_SIZE; i++) {
|
||||||
uint16_t sample;
|
uint16_t sample;
|
||||||
@@ -151,100 +339,165 @@ void CIO::process()
|
|||||||
if (m_detect && (sample == 0U || sample == 4095U))
|
if (m_detect && (sample == 0U || sample == 4095U))
|
||||||
m_adcOverflow++;
|
m_adcOverflow++;
|
||||||
|
|
||||||
q15_t res1 = q15_t(sample) - DC_OFFSET;
|
q15_t res1 = q15_t(sample) - m_rxDCOffset;
|
||||||
q31_t res2 = res1 * m_rxLevel;
|
q31_t res2 = res1 * m_rxLevel;
|
||||||
samples[i] = q15_t(__SSAT((res2 >> 15), 16));
|
samples[i] = q15_t(__SSAT((res2 >> 15), 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle the case of the oscillator not being accurate enough
|
|
||||||
if (m_sampleCount > 0U) {
|
|
||||||
m_count += RX_BLOCK_SIZE;
|
|
||||||
|
|
||||||
if (m_count >= m_sampleCount) {
|
|
||||||
if (m_sampleInsert) {
|
|
||||||
blockSize++;
|
|
||||||
samples[RX_BLOCK_SIZE] = 0;
|
|
||||||
for (int8_t i = RX_BLOCK_SIZE - 1; i >= 0; i--)
|
|
||||||
control[i + 1] = control[i];
|
|
||||||
} else {
|
|
||||||
blockSize--;
|
|
||||||
for (uint8_t i = 0U; i < (RX_BLOCK_SIZE - 1U); i++)
|
|
||||||
control[i] = control[i + 1U];
|
|
||||||
}
|
|
||||||
|
|
||||||
m_count -= m_sampleCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_lockout)
|
if (m_lockout)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#if defined(USE_DCBLOCKER)
|
||||||
|
q31_t q31Samples[RX_BLOCK_SIZE];
|
||||||
|
::arm_q15_to_q31(samples, q31Samples, RX_BLOCK_SIZE);
|
||||||
|
|
||||||
|
q31_t dcValues[RX_BLOCK_SIZE];
|
||||||
|
::arm_biquad_cascade_df1_q31(&m_dcFilter, q31Samples, dcValues, RX_BLOCK_SIZE);
|
||||||
|
|
||||||
|
q31_t dcLevel = 0;
|
||||||
|
for (uint8_t i = 0U; i < RX_BLOCK_SIZE; i++)
|
||||||
|
dcLevel += dcValues[i];
|
||||||
|
dcLevel /= RX_BLOCK_SIZE;
|
||||||
|
|
||||||
|
q15_t offset = q15_t(__SSAT((dcLevel >> 16), 16));;
|
||||||
|
|
||||||
|
q15_t dcSamples[RX_BLOCK_SIZE];
|
||||||
|
for (uint8_t i = 0U; i < RX_BLOCK_SIZE; i++)
|
||||||
|
dcSamples[i] = samples[i] - offset;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (m_modemState == STATE_IDLE) {
|
if (m_modemState == STATE_IDLE) {
|
||||||
if (m_dstarEnable) {
|
if (m_dstarEnable) {
|
||||||
q15_t GMSKVals[RX_BLOCK_SIZE + 1U];
|
q15_t GMSKVals[RX_BLOCK_SIZE];
|
||||||
::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, blockSize);
|
#if defined(USE_DCBLOCKER)
|
||||||
|
#if !defined (DSTARBOXCAR)
|
||||||
dstarRX.samples(GMSKVals, blockSize);
|
::arm_fir_fast_q15(&m_gaussianFilter, dcSamples, GMSKVals, RX_BLOCK_SIZE);
|
||||||
|
#else
|
||||||
|
::arm_fir_fast_q15(&m_boxcarFilter, dcSamples, GMSKVals, RX_BLOCK_SIZE);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if !defined (DSTARBOXCAR)
|
||||||
|
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
|
||||||
|
#else
|
||||||
|
::arm_fir_fast_q15(&m_boxcarFilter, samples, GMSKVals, RX_BLOCK_SIZE);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
dstarRX.samples(GMSKVals, rssi, RX_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_dmrEnable || m_ysfEnable || m_p25Enable) {
|
if (m_p25Enable) {
|
||||||
q15_t C4FSKVals[RX_BLOCK_SIZE + 1U];
|
q15_t P25Vals[RX_BLOCK_SIZE];
|
||||||
::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, blockSize);
|
#if defined(USE_DCBLOCKER)
|
||||||
|
::arm_fir_fast_q15(&m_boxcarFilter, dcSamples, P25Vals, RX_BLOCK_SIZE);
|
||||||
|
#else
|
||||||
|
::arm_fir_fast_q15(&m_boxcarFilter, samples, P25Vals, RX_BLOCK_SIZE);
|
||||||
|
#endif
|
||||||
|
p25RX.samples(P25Vals, rssi, RX_BLOCK_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_nxdnEnable) {
|
||||||
|
q15_t NXDNValsTmp[RX_BLOCK_SIZE];
|
||||||
|
#if defined(USE_DCBLOCKER)
|
||||||
|
::arm_fir_fast_q15(&m_nxdnFilter, dcSamples, NXDNValsTmp, RX_BLOCK_SIZE);
|
||||||
|
#else
|
||||||
|
::arm_fir_fast_q15(&m_nxdnFilter, samples, NXDNValsTmp, RX_BLOCK_SIZE);
|
||||||
|
#endif
|
||||||
|
q15_t NXDNVals[RX_BLOCK_SIZE];
|
||||||
|
::arm_fir_fast_q15(&m_nxdnISincFilter, NXDNValsTmp, NXDNVals, RX_BLOCK_SIZE);
|
||||||
|
|
||||||
|
nxdnRX.samples(NXDNVals, rssi, RX_BLOCK_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_dmrEnable || m_ysfEnable) {
|
||||||
|
q15_t RRCVals[RX_BLOCK_SIZE];
|
||||||
|
::arm_fir_fast_q15(&m_rrcFilter, samples, RRCVals, RX_BLOCK_SIZE);
|
||||||
|
|
||||||
|
if (m_ysfEnable)
|
||||||
|
ysfRX.samples(RRCVals, rssi, RX_BLOCK_SIZE);
|
||||||
|
|
||||||
if (m_dmrEnable) {
|
if (m_dmrEnable) {
|
||||||
if (m_duplex)
|
if (m_duplex)
|
||||||
dmrIdleRX.samples(C4FSKVals, blockSize);
|
dmrIdleRX.samples(RRCVals, RX_BLOCK_SIZE);
|
||||||
else
|
else
|
||||||
dmrDMORX.samples(C4FSKVals, rssi, blockSize);
|
dmrDMORX.samples(RRCVals, rssi, RX_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_ysfEnable)
|
|
||||||
ysfRX.samples(C4FSKVals, blockSize);
|
|
||||||
|
|
||||||
if (m_p25Enable)
|
|
||||||
p25RX.samples(C4FSKVals, blockSize);
|
|
||||||
}
|
}
|
||||||
} else if (m_modemState == STATE_DSTAR) {
|
} else if (m_modemState == STATE_DSTAR) {
|
||||||
if (m_dstarEnable) {
|
if (m_dstarEnable) {
|
||||||
q15_t GMSKVals[RX_BLOCK_SIZE + 1U];
|
q15_t GMSKVals[RX_BLOCK_SIZE];
|
||||||
::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, blockSize);
|
#if defined(USE_DCBLOCKER)
|
||||||
|
#if !defined (DSTARBOXCAR)
|
||||||
dstarRX.samples(GMSKVals, blockSize);
|
::arm_fir_fast_q15(&m_gaussianFilter, dcSamples, GMSKVals, RX_BLOCK_SIZE);
|
||||||
|
#else
|
||||||
|
::arm_fir_fast_q15(&m_boxcarFilter, dcSamples, GMSKVals, RX_BLOCK_SIZE);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if !defined (DSTARBOXCAR)
|
||||||
|
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
|
||||||
|
#else
|
||||||
|
::arm_fir_fast_q15(&m_boxcarFilter, samples, GMSKVals, RX_BLOCK_SIZE);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
dstarRX.samples(GMSKVals, rssi, RX_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
} else if (m_modemState == STATE_DMR) {
|
} else if (m_modemState == STATE_DMR) {
|
||||||
if (m_dmrEnable) {
|
if (m_dmrEnable) {
|
||||||
q15_t C4FSKVals[RX_BLOCK_SIZE + 1U];
|
q15_t DMRVals[RX_BLOCK_SIZE];
|
||||||
::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, blockSize);
|
::arm_fir_fast_q15(&m_rrcFilter, samples, DMRVals, RX_BLOCK_SIZE);
|
||||||
|
|
||||||
if (m_duplex) {
|
if (m_duplex) {
|
||||||
// If the transmitter isn't on, use the DMR idle RX to detect the wakeup CSBKs
|
// If the transmitter isn't on, use the DMR idle RX to detect the wakeup CSBKs
|
||||||
if (m_tx)
|
if (m_tx)
|
||||||
dmrRX.samples(C4FSKVals, rssi, control, blockSize);
|
dmrRX.samples(DMRVals, rssi, control, RX_BLOCK_SIZE);
|
||||||
else
|
else
|
||||||
dmrIdleRX.samples(C4FSKVals, blockSize);
|
dmrIdleRX.samples(DMRVals, RX_BLOCK_SIZE);
|
||||||
} else {
|
} else {
|
||||||
dmrDMORX.samples(C4FSKVals, rssi, blockSize);
|
dmrDMORX.samples(DMRVals, rssi, RX_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (m_modemState == STATE_YSF) {
|
} else if (m_modemState == STATE_YSF) {
|
||||||
if (m_ysfEnable) {
|
if (m_ysfEnable) {
|
||||||
q15_t C4FSKVals[RX_BLOCK_SIZE + 1U];
|
q15_t YSFVals[RX_BLOCK_SIZE];
|
||||||
::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, blockSize);
|
#if defined(USE_DCBLOCKER)
|
||||||
|
::arm_fir_fast_q15(&m_rrcFilter, dcSamples, YSFVals, RX_BLOCK_SIZE);
|
||||||
ysfRX.samples(C4FSKVals, blockSize);
|
#else
|
||||||
|
::arm_fir_fast_q15(&m_rrcFilter, samples, YSFVals, RX_BLOCK_SIZE);
|
||||||
|
#endif
|
||||||
|
ysfRX.samples(YSFVals, rssi, RX_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
} else if (m_modemState == STATE_P25) {
|
} else if (m_modemState == STATE_P25) {
|
||||||
if (m_p25Enable) {
|
if (m_p25Enable) {
|
||||||
q15_t C4FSKVals[RX_BLOCK_SIZE + 1U];
|
q15_t P25Vals[RX_BLOCK_SIZE];
|
||||||
::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, blockSize);
|
#if defined(USE_DCBLOCKER)
|
||||||
|
::arm_fir_fast_q15(&m_boxcarFilter, dcSamples, P25Vals, RX_BLOCK_SIZE);
|
||||||
|
#else
|
||||||
|
::arm_fir_fast_q15(&m_boxcarFilter, samples, P25Vals, RX_BLOCK_SIZE);
|
||||||
|
#endif
|
||||||
|
p25RX.samples(P25Vals, rssi, RX_BLOCK_SIZE);
|
||||||
|
}
|
||||||
|
} else if (m_modemState == STATE_NXDN) {
|
||||||
|
if (m_nxdnEnable) {
|
||||||
|
q15_t NXDNValsTmp[RX_BLOCK_SIZE];
|
||||||
|
#if defined(USE_DCBLOCKER)
|
||||||
|
::arm_fir_fast_q15(&m_nxdnFilter, dcSamples, NXDNValsTmp, RX_BLOCK_SIZE);
|
||||||
|
#else
|
||||||
|
::arm_fir_fast_q15(&m_nxdnFilter, samples, NXDNValsTmp, RX_BLOCK_SIZE);
|
||||||
|
#endif
|
||||||
|
q15_t NXDNVals[RX_BLOCK_SIZE];
|
||||||
|
::arm_fir_fast_q15(&m_nxdnISincFilter, NXDNValsTmp, NXDNVals, RX_BLOCK_SIZE);
|
||||||
|
|
||||||
p25RX.samples(C4FSKVals, blockSize);
|
nxdnRX.samples(NXDNVals, rssi, RX_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
} else if (m_modemState == STATE_DSTARCAL) {
|
} else if (m_modemState == STATE_DSTARCAL) {
|
||||||
q15_t GMSKVals[RX_BLOCK_SIZE + 1U];
|
q15_t GMSKVals[RX_BLOCK_SIZE];
|
||||||
::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, blockSize);
|
#if !defined (DSTARBOXCAR)
|
||||||
|
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
|
||||||
calDStarRX.samples(GMSKVals, blockSize);
|
#else
|
||||||
|
::arm_fir_fast_q15(&m_boxcarFilter, samples, GMSKVals, RX_BLOCK_SIZE);
|
||||||
|
#endif
|
||||||
|
calDStarRX.samples(GMSKVals, RX_BLOCK_SIZE);
|
||||||
|
} else if (m_modemState == STATE_RSSICAL) {
|
||||||
|
calRSSI.samples(rssi, RX_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -277,6 +530,12 @@ void CIO::write(MMDVM_STATE mode, q15_t* samples, uint16_t length, const uint8_t
|
|||||||
case STATE_P25:
|
case STATE_P25:
|
||||||
txLevel = m_p25TXLevel;
|
txLevel = m_p25TXLevel;
|
||||||
break;
|
break;
|
||||||
|
case STATE_NXDN:
|
||||||
|
txLevel = m_nxdnTXLevel;
|
||||||
|
break;
|
||||||
|
case STATE_POCSAG:
|
||||||
|
txLevel = m_pocsagTXLevel;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
txLevel = m_cwIdTXLevel;
|
txLevel = m_cwIdTXLevel;
|
||||||
break;
|
break;
|
||||||
@@ -285,7 +544,7 @@ void CIO::write(MMDVM_STATE mode, q15_t* samples, uint16_t length, const uint8_t
|
|||||||
for (uint16_t i = 0U; i < length; i++) {
|
for (uint16_t i = 0U; i < length; i++) {
|
||||||
q31_t res1 = samples[i] * txLevel;
|
q31_t res1 = samples[i] * txLevel;
|
||||||
q15_t res2 = q15_t(__SSAT((res1 >> 15), 16));
|
q15_t res2 = q15_t(__SSAT((res1 >> 15), 16));
|
||||||
uint16_t res3 = uint16_t(res2 + DC_OFFSET);
|
uint16_t res3 = uint16_t(res2 + m_txDCOffset);
|
||||||
|
|
||||||
// Detect DAC overflow
|
// Detect DAC overflow
|
||||||
if (res3 > 4095U)
|
if (res3 > 4095U)
|
||||||
@@ -318,33 +577,42 @@ void CIO::setADCDetection(bool detect)
|
|||||||
|
|
||||||
void CIO::setMode()
|
void CIO::setMode()
|
||||||
{
|
{
|
||||||
#if defined(ARDUINO_MODE_PINS)
|
#if defined(MODE_PINS)
|
||||||
setDStarInt(m_modemState == STATE_DSTAR);
|
setDStarInt(m_modemState == STATE_DSTAR);
|
||||||
setDMRInt(m_modemState == STATE_DMR);
|
setDMRInt(m_modemState == STATE_DMR);
|
||||||
setYSFInt(m_modemState == STATE_YSF);
|
setYSFInt(m_modemState == STATE_YSF);
|
||||||
setP25Int(m_modemState == STATE_P25);
|
setP25Int(m_modemState == STATE_P25);
|
||||||
|
setNXDNInt(m_modemState == STATE_NXDN);
|
||||||
|
setPOCSAGInt(m_modemState == STATE_POCSAG);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void CIO::setParameters(bool rxInvert, bool txInvert, bool pttInvert, uint8_t rxLevel, uint8_t cwIdTXLevel, uint8_t dstarTXLevel, uint8_t dmrTXLevel, uint8_t ysfTXLevel, uint8_t p25TXLevel)
|
void CIO::setParameters(bool rxInvert, bool txInvert, bool pttInvert, uint8_t rxLevel, uint8_t cwIdTXLevel, uint8_t dstarTXLevel, uint8_t dmrTXLevel, uint8_t ysfTXLevel, uint8_t p25TXLevel, uint8_t nxdnTXLevel, uint8_t pocsagTXLevel, int16_t txDCOffset, int16_t rxDCOffset)
|
||||||
{
|
{
|
||||||
m_pttInvert = pttInvert;
|
m_pttInvert = pttInvert;
|
||||||
|
|
||||||
m_rxLevel = q15_t(rxLevel * 128);
|
m_rxLevel = q15_t(rxLevel * 128);
|
||||||
m_cwIdTXLevel = q15_t(cwIdTXLevel * 128);
|
m_cwIdTXLevel = q15_t(cwIdTXLevel * 128);
|
||||||
m_dstarTXLevel = q15_t(dstarTXLevel * 128);
|
m_dstarTXLevel = q15_t(dstarTXLevel * 128);
|
||||||
m_dmrTXLevel = q15_t(dmrTXLevel * 128);
|
m_dmrTXLevel = q15_t(dmrTXLevel * 128);
|
||||||
m_ysfTXLevel = q15_t(ysfTXLevel * 128);
|
m_ysfTXLevel = q15_t(ysfTXLevel * 128);
|
||||||
m_p25TXLevel = q15_t(p25TXLevel * 128);
|
m_p25TXLevel = q15_t(p25TXLevel * 128);
|
||||||
|
m_nxdnTXLevel = q15_t(nxdnTXLevel * 128);
|
||||||
|
m_pocsagTXLevel = q15_t(pocsagTXLevel * 128);
|
||||||
|
|
||||||
|
m_rxDCOffset = DC_OFFSET + rxDCOffset;
|
||||||
|
m_txDCOffset = DC_OFFSET + txDCOffset;
|
||||||
|
|
||||||
if (rxInvert)
|
if (rxInvert)
|
||||||
m_rxLevel = -m_rxLevel;
|
m_rxLevel = -m_rxLevel;
|
||||||
|
|
||||||
if (txInvert) {
|
if (txInvert) {
|
||||||
m_dstarTXLevel = -m_dstarTXLevel;
|
m_dstarTXLevel = -m_dstarTXLevel;
|
||||||
m_dmrTXLevel = -m_dmrTXLevel;
|
m_dmrTXLevel = -m_dmrTXLevel;
|
||||||
m_ysfTXLevel = -m_ysfTXLevel;
|
m_ysfTXLevel = -m_ysfTXLevel;
|
||||||
m_p25TXLevel = -m_p25TXLevel;
|
m_p25TXLevel = -m_p25TXLevel;
|
||||||
|
m_nxdnTXLevel = -m_nxdnTXLevel;
|
||||||
|
m_pocsagTXLevel = -m_pocsagTXLevel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,11 +621,6 @@ void CIO::getOverflow(bool& adcOverflow, bool& dacOverflow)
|
|||||||
adcOverflow = m_adcOverflow > 0U;
|
adcOverflow = m_adcOverflow > 0U;
|
||||||
dacOverflow = m_dacOverflow > 0U;
|
dacOverflow = m_dacOverflow > 0U;
|
||||||
|
|
||||||
#if defined(WANT_DEBUG)
|
|
||||||
if (m_adcOverflow > 0U || m_dacOverflow > 0U)
|
|
||||||
DEBUG3("IO: adc/dac", m_adcOverflow, m_dacOverflow);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_adcOverflow = 0U;
|
m_adcOverflow = 0U;
|
||||||
m_dacOverflow = 0U;
|
m_dacOverflow = 0U;
|
||||||
}
|
}
|
||||||
@@ -377,6 +640,11 @@ void CIO::resetWatchdog()
|
|||||||
m_watchdog = 0U;
|
m_watchdog = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t CIO::getWatchdog()
|
||||||
|
{
|
||||||
|
return m_watchdog;
|
||||||
|
}
|
||||||
|
|
||||||
bool CIO::hasLockout() const
|
bool CIO::hasLockout() const
|
||||||
{
|
{
|
||||||
return m_lockout;
|
return m_lockout;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -40,9 +40,9 @@ public:
|
|||||||
void setADCDetection(bool detect);
|
void setADCDetection(bool detect);
|
||||||
void setMode();
|
void setMode();
|
||||||
|
|
||||||
void interrupt(uint8_t source);
|
void interrupt();
|
||||||
|
|
||||||
void setParameters(bool rxInvert, bool txInvert, bool pttInvert, uint8_t rxLevel, uint8_t cwIdTXLevel, uint8_t dstarTXLevel, uint8_t dmrTXLevel, uint8_t ysfTXLevel, uint8_t p25TXLevel);
|
void setParameters(bool rxInvert, bool txInvert, bool pttInvert, uint8_t rxLevel, uint8_t cwIdTXLevel, uint8_t dstarTXLevel, uint8_t dmrTXLevel, uint8_t ysfTXLevel, uint8_t p25TXLevel, uint8_t nxdnTXLevel, uint8_t pocsagTXLevel, int16_t txDCOffset, int16_t rxDCOffset);
|
||||||
|
|
||||||
void getOverflow(bool& adcOverflow, bool& dacOverflow);
|
void getOverflow(bool& adcOverflow, bool& dacOverflow);
|
||||||
|
|
||||||
@@ -52,6 +52,9 @@ public:
|
|||||||
bool hasLockout() const;
|
bool hasLockout() const;
|
||||||
|
|
||||||
void resetWatchdog();
|
void resetWatchdog();
|
||||||
|
uint32_t getWatchdog();
|
||||||
|
|
||||||
|
void selfTest();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_started;
|
bool m_started;
|
||||||
@@ -60,10 +63,23 @@ private:
|
|||||||
CSampleRB m_txBuffer;
|
CSampleRB m_txBuffer;
|
||||||
CRSSIRB m_rssiBuffer;
|
CRSSIRB m_rssiBuffer;
|
||||||
|
|
||||||
arm_fir_instance_q15 m_C4FSKFilter;
|
arm_biquad_casd_df1_inst_q31 m_dcFilter;
|
||||||
arm_fir_instance_q15 m_GMSKFilter;
|
q31_t m_dcState[4];
|
||||||
q15_t m_C4FSKState[70U]; // NoTaps + BlockSize - 1, 42 + 20 - 1 plus some spare
|
|
||||||
q15_t m_GMSKState[40U]; // NoTaps + BlockSize - 1, 12 + 20 - 1 plus some spare
|
arm_fir_instance_q15 m_rrcFilter;
|
||||||
|
#if !defined (DSTARBOXCAR)
|
||||||
|
arm_fir_instance_q15 m_gaussianFilter;
|
||||||
|
#endif
|
||||||
|
arm_fir_instance_q15 m_boxcarFilter;
|
||||||
|
arm_fir_instance_q15 m_nxdnFilter;
|
||||||
|
arm_fir_instance_q15 m_nxdnISincFilter;
|
||||||
|
q15_t m_rrcState[140U]; // NoTaps + BlockSize - 1, 82 + 20 - 1 plus some spare
|
||||||
|
#if !defined (DSTARBOXCAR)
|
||||||
|
q15_t m_gaussianState[80U]; // NoTaps + BlockSize - 1, 24 + 20 - 1 plus some spare
|
||||||
|
#endif
|
||||||
|
q15_t m_boxcarState[60U]; // NoTaps + BlockSize - 1, 12 + 20 - 1 plus some spare
|
||||||
|
q15_t m_nxdnState[220U]; // NoTaps + BlockSize - 1, 162 + 20 - 1 plus some spare
|
||||||
|
q15_t m_nxdnISincState[60U]; // NoTaps + BlockSize - 1, 32 + 20 - 1 plus some spare
|
||||||
|
|
||||||
bool m_pttInvert;
|
bool m_pttInvert;
|
||||||
q15_t m_rxLevel;
|
q15_t m_rxLevel;
|
||||||
@@ -72,6 +88,11 @@ private:
|
|||||||
q15_t m_dmrTXLevel;
|
q15_t m_dmrTXLevel;
|
||||||
q15_t m_ysfTXLevel;
|
q15_t m_ysfTXLevel;
|
||||||
q15_t m_p25TXLevel;
|
q15_t m_p25TXLevel;
|
||||||
|
q15_t m_nxdnTXLevel;
|
||||||
|
q15_t m_pocsagTXLevel;
|
||||||
|
|
||||||
|
uint16_t m_rxDCOffset;
|
||||||
|
uint16_t m_txDCOffset;
|
||||||
|
|
||||||
uint32_t m_ledCount;
|
uint32_t m_ledCount;
|
||||||
bool m_ledValue;
|
bool m_ledValue;
|
||||||
@@ -81,8 +102,6 @@ private:
|
|||||||
uint16_t m_adcOverflow;
|
uint16_t m_adcOverflow;
|
||||||
uint16_t m_dacOverflow;
|
uint16_t m_dacOverflow;
|
||||||
|
|
||||||
uint32_t m_count;
|
|
||||||
|
|
||||||
volatile uint32_t m_watchdog;
|
volatile uint32_t m_watchdog;
|
||||||
|
|
||||||
bool m_lockout;
|
bool m_lockout;
|
||||||
@@ -101,6 +120,10 @@ private:
|
|||||||
void setDMRInt(bool on);
|
void setDMRInt(bool on);
|
||||||
void setYSFInt(bool on);
|
void setYSFInt(bool on);
|
||||||
void setP25Int(bool on);
|
void setP25Int(bool on);
|
||||||
|
void setNXDNInt(bool on);
|
||||||
|
void setPOCSAGInt(bool on);
|
||||||
|
|
||||||
|
void delayInt(unsigned int dly);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
|
||||||
* Copyright (C) 2015 by Jim Mclaughlin KI6ZUM
|
* Copyright (C) 2015 by Jim Mclaughlin KI6ZUM
|
||||||
* Copyright (C) 2016 by Colin Durbridge G4EML
|
* Copyright (C) 2016 by Colin Durbridge G4EML
|
||||||
*
|
*
|
||||||
@@ -33,6 +33,8 @@
|
|||||||
#define PIN_DMR 17
|
#define PIN_DMR 17
|
||||||
#define PIN_YSF 18
|
#define PIN_YSF 18
|
||||||
#define PIN_P25 19
|
#define PIN_P25 19
|
||||||
|
#define PIN_NXDN 20
|
||||||
|
#define PIN_POCSAG 4
|
||||||
#define ADC_CHER_Chan (1<<7) // ADC on Due pin A0 - Due AD7 - (1 << 7)
|
#define ADC_CHER_Chan (1<<7) // ADC on Due pin A0 - Due AD7 - (1 << 7)
|
||||||
#define ADC_ISR_EOC_Chan ADC_ISR_EOC7
|
#define ADC_ISR_EOC_Chan ADC_ISR_EOC7
|
||||||
#define ADC_CDR_Chan 7
|
#define ADC_CDR_Chan 7
|
||||||
@@ -46,11 +48,15 @@
|
|||||||
#define PIN_DMR 8
|
#define PIN_DMR 8
|
||||||
#define PIN_YSF 7
|
#define PIN_YSF 7
|
||||||
#define PIN_P25 6
|
#define PIN_P25 6
|
||||||
|
#define PIN_NXDN 5
|
||||||
|
#define PIN_POCSAG 4
|
||||||
#define ADC_CHER_Chan (1<<13) // ADC on Due pin A11 - Due AD13 - (1 << 13)
|
#define ADC_CHER_Chan (1<<13) // ADC on Due pin A11 - Due AD13 - (1 << 13)
|
||||||
#define ADC_ISR_EOC_Chan ADC_ISR_EOC13
|
#define ADC_ISR_EOC_Chan ADC_ISR_EOC13
|
||||||
#define ADC_CDR_Chan 13
|
#define ADC_CDR_Chan 13
|
||||||
#define DACC_MR_USER_SEL_Chan DACC_MR_USER_SEL_CHANNEL1 // DAC on Due DAC1
|
#define DACC_MR_USER_SEL_Chan DACC_MR_USER_SEL_CHANNEL1 // DAC on Due DAC1
|
||||||
#define DACC_CHER_Chan DACC_CHER_CH1
|
#define DACC_CHER_Chan DACC_CHER_CH1
|
||||||
|
#define RSSI_CHER_Chan (1<<1) // ADC on Due pin A6 - Due AD1 - (1 << 1)
|
||||||
|
#define RSSI_CDR_Chan 1
|
||||||
#elif defined(ARDUINO_DUE_NTH)
|
#elif defined(ARDUINO_DUE_NTH)
|
||||||
#define PIN_COS A7
|
#define PIN_COS A7
|
||||||
#define PIN_PTT A8
|
#define PIN_PTT A8
|
||||||
@@ -59,11 +65,15 @@
|
|||||||
#define PIN_DMR 8
|
#define PIN_DMR 8
|
||||||
#define PIN_YSF 7
|
#define PIN_YSF 7
|
||||||
#define PIN_P25 6
|
#define PIN_P25 6
|
||||||
|
#define PIN_NXDN 5
|
||||||
|
#define PIN_POCSAG 4
|
||||||
#define ADC_CHER_Chan (1<<7) // ADC on Due pin A0 - Due AD7 - (1 << 7)
|
#define ADC_CHER_Chan (1<<7) // ADC on Due pin A0 - Due AD7 - (1 << 7)
|
||||||
#define ADC_ISR_EOC_Chan ADC_ISR_EOC7
|
#define ADC_ISR_EOC_Chan ADC_ISR_EOC7
|
||||||
#define ADC_CDR_Chan 7
|
#define ADC_CDR_Chan 7
|
||||||
#define DACC_MR_USER_SEL_Chan DACC_MR_USER_SEL_CHANNEL0 // DAC on Due DAC0
|
#define DACC_MR_USER_SEL_Chan DACC_MR_USER_SEL_CHANNEL0 // DAC on Due DAC0
|
||||||
#define DACC_CHER_Chan DACC_CHER_CH0
|
#define DACC_CHER_Chan DACC_CHER_CH0
|
||||||
|
#define RSSI_CHER_Chan (1<<1) // ADC on Due pin A6 - Due AD1 - (1 << 1)
|
||||||
|
#define RSSI_CDR_Chan 1
|
||||||
#else
|
#else
|
||||||
#error "Either ARDUINO_DUE_PAPA, ARDUINO_DUE_ZUM_V10, or ARDUINO_DUE_NTH need to be defined"
|
#error "Either ARDUINO_DUE_PAPA, ARDUINO_DUE_ZUM_V10, or ARDUINO_DUE_NTH need to be defined"
|
||||||
#endif
|
#endif
|
||||||
@@ -73,7 +83,7 @@ const uint16_t DC_OFFSET = 2048U;
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
void ADC_Handler()
|
void ADC_Handler()
|
||||||
{
|
{
|
||||||
io.interrupt(0U);
|
io.interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,26 +95,35 @@ void CIO::initInt()
|
|||||||
pinMode(PIN_LED, OUTPUT);
|
pinMode(PIN_LED, OUTPUT);
|
||||||
pinMode(PIN_COS, INPUT);
|
pinMode(PIN_COS, INPUT);
|
||||||
|
|
||||||
#if defined(ARDUINO_MODE_PINS)
|
#if defined(MODE_LEDS)
|
||||||
// Set up the mode output pins
|
// Set up the mode output pins
|
||||||
pinMode(PIN_DSTAR, OUTPUT);
|
pinMode(PIN_DSTAR, OUTPUT);
|
||||||
pinMode(PIN_DMR, OUTPUT);
|
pinMode(PIN_DMR, OUTPUT);
|
||||||
pinMode(PIN_YSF, OUTPUT);
|
pinMode(PIN_YSF, OUTPUT);
|
||||||
pinMode(PIN_P25, OUTPUT);
|
pinMode(PIN_P25, OUTPUT);
|
||||||
|
#if !defined(USE_ALTERNATE_NXDN_LEDS)
|
||||||
|
pinMode(PIN_NXDN, OUTPUT);
|
||||||
|
#endif
|
||||||
|
#if !defined(USE_ALTERNATE_POCSAG_LEDS)
|
||||||
|
pinMode(PIN_POCSAG, OUTPUT);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void CIO::startInt()
|
void CIO::startInt()
|
||||||
{
|
{
|
||||||
if (ADC->ADC_ISR & ADC_ISR_EOC_Chan) // Ensure there was an End-of-Conversion and we read the ISR reg
|
if (ADC->ADC_ISR & ADC_ISR_EOC_Chan) // Ensure there was an End-of-Conversion and we read the ISR reg
|
||||||
io.interrupt(0U);
|
io.interrupt();
|
||||||
|
|
||||||
// Set up the ADC
|
// Set up the ADC
|
||||||
NVIC_EnableIRQ(ADC_IRQn); // Enable ADC interrupt vector
|
NVIC_EnableIRQ(ADC_IRQn); // Enable ADC interrupt vector
|
||||||
ADC->ADC_IDR = 0xFFFFFFFF; // Disable interrupts
|
ADC->ADC_IDR = 0xFFFFFFFF; // Disable interrupts
|
||||||
ADC->ADC_IER = ADC_CHER_Chan; // Enable End-Of-Conv interrupt
|
ADC->ADC_IER = ADC_CHER_Chan; // Enable End-Of-Conv interrupt
|
||||||
ADC->ADC_CHDR = 0xFFFF; // Disable all channels
|
ADC->ADC_CHDR = 0xFFFF; // Disable all channels
|
||||||
ADC->ADC_CHER = ADC_CHER_Chan; // Enable just one channel
|
ADC->ADC_CHER = ADC_CHER_Chan; // Enable rx input channel
|
||||||
|
#if defined(SEND_RSSI_DATA)
|
||||||
|
ADC->ADC_CHER |= RSSI_CHER_Chan; // and RSSI input
|
||||||
|
#endif
|
||||||
ADC->ADC_CGR = 0x15555555; // All gains set to x1
|
ADC->ADC_CGR = 0x15555555; // All gains set to x1
|
||||||
ADC->ADC_COR = 0x00000000; // All offsets off
|
ADC->ADC_COR = 0x00000000; // All offsets off
|
||||||
ADC->ADC_MR = (ADC->ADC_MR & 0xFFFFFFF0) | (1 << 1) | ADC_MR_TRGEN; // 1 = trig source TIO from TC0
|
ADC->ADC_MR = (ADC->ADC_MR & 0xFFFFFFF0) | (1 << 1) | ADC_MR_TRGEN; // 1 = trig source TIO from TC0
|
||||||
@@ -133,11 +152,11 @@ void CIO::startInt()
|
|||||||
TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_CLEAR |
|
TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_CLEAR |
|
||||||
TC_CMR_BCPB_CLEAR | TC_CMR_BCPC_CLEAR;
|
TC_CMR_BCPB_CLEAR | TC_CMR_BCPC_CLEAR;
|
||||||
#if defined(EXTERNAL_OSC)
|
#if defined(EXTERNAL_OSC)
|
||||||
t->TC_RC = EXTERNAL_OSC / 24000; // Counter resets on RC, so sets period in terms of the external clock
|
t->TC_RC = EXTERNAL_OSC / 48000; // Counter resets on RC, so sets period in terms of the external clock
|
||||||
t->TC_RA = EXTERNAL_OSC / 48000; // Roughly square wave
|
t->TC_RA = EXTERNAL_OSC / 96000; // Roughly square wave
|
||||||
#else
|
#else
|
||||||
t->TC_RC = 1750; // Counter resets on RC, so sets period in terms of 42MHz internal clock
|
t->TC_RC = 875; // Counter resets on RC, so sets period in terms of 42MHz internal clock
|
||||||
t->TC_RA = 880; // Roughly square wave
|
t->TC_RA = 438; // Roughly square wave
|
||||||
#endif
|
#endif
|
||||||
t->TC_CMR = (t->TC_CMR & 0xFFF0FFFF) | TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_SET; // Set clear and set from RA and RC compares
|
t->TC_CMR = (t->TC_CMR & 0xFFF0FFFF) | TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_SET; // Set clear and set from RA and RC compares
|
||||||
t->TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG; // re-enable local clocking and switch to hardware trigger source.
|
t->TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG; // re-enable local clocking and switch to hardware trigger source.
|
||||||
@@ -157,7 +176,7 @@ void CIO::startInt()
|
|||||||
digitalWrite(PIN_LED, HIGH);
|
digitalWrite(PIN_LED, HIGH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CIO::interrupt(uint8_t source)
|
void CIO::interrupt()
|
||||||
{
|
{
|
||||||
if ((ADC->ADC_ISR & ADC_ISR_EOC_Chan) == ADC_ISR_EOC_Chan) { // Ensure there was an End-of-Conversion and we read the ISR reg
|
if ((ADC->ADC_ISR & ADC_ISR_EOC_Chan) == ADC_ISR_EOC_Chan) { // Ensure there was an End-of-Conversion and we read the ISR reg
|
||||||
uint8_t control = MARK_NONE;
|
uint8_t control = MARK_NONE;
|
||||||
@@ -169,7 +188,11 @@ void CIO::interrupt(uint8_t source)
|
|||||||
sample = ADC->ADC_CDR[ADC_CDR_Chan];
|
sample = ADC->ADC_CDR[ADC_CDR_Chan];
|
||||||
m_rxBuffer.put(sample, control);
|
m_rxBuffer.put(sample, control);
|
||||||
|
|
||||||
|
#if defined(SEND_RSSI_DATA)
|
||||||
|
m_rssiBuffer.put(ADC->ADC_CDR[RSSI_CDR_Chan]);
|
||||||
|
#else
|
||||||
m_rssiBuffer.put(0U);
|
m_rssiBuffer.put(0U);
|
||||||
|
#endif
|
||||||
|
|
||||||
m_watchdog++;
|
m_watchdog++;
|
||||||
}
|
}
|
||||||
@@ -215,5 +238,30 @@ void CIO::setP25Int(bool on)
|
|||||||
digitalWrite(PIN_P25, on ? HIGH : LOW);
|
digitalWrite(PIN_P25, on ? HIGH : LOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CIO::setNXDNInt(bool on)
|
||||||
|
{
|
||||||
|
#if defined(USE_ALTERNATE_NXDN_LEDS)
|
||||||
|
digitalWrite(PIN_YSF, on ? HIGH : LOW);
|
||||||
|
digitalWrite(PIN_P25, on ? HIGH : LOW);
|
||||||
|
#else
|
||||||
|
digitalWrite(PIN_NXDN, on ? HIGH : LOW);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIO::setPOCSAGInt(bool on)
|
||||||
|
{
|
||||||
|
#if defined(USE_ALTERNATE_POCSAG_LEDS)
|
||||||
|
digitalWrite(PIN_DSTAR, on ? HIGH : LOW);
|
||||||
|
digitalWrite(PIN_DMR, on ? HIGH : LOW);
|
||||||
|
#else
|
||||||
|
digitalWrite(PIN_POCSAG, on ? HIGH : LOW);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIO::delayInt(unsigned int dly)
|
||||||
|
{
|
||||||
|
delay(dly);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+466
@@ -0,0 +1,466 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 by Jim McLaughlin KI6ZUM
|
||||||
|
* Copyright (C) 2016, 2017 by Andy Uribe CA6JAU
|
||||||
|
* Copyright (C) 2017,2018 by Jonathan Naylor G4KLX
|
||||||
|
* Copyright (C) 2017 by Wojciech Krutnik N0CALL
|
||||||
|
*
|
||||||
|
* 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
#include "Globals.h"
|
||||||
|
#include "IO.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(STM32F1)
|
||||||
|
|
||||||
|
#if defined(STM32F1_POG)
|
||||||
|
/*
|
||||||
|
Pin definitions for STM32F1 POG Board:
|
||||||
|
|
||||||
|
PTT PB12 output
|
||||||
|
COSLED PB5 output
|
||||||
|
LED PB4 output
|
||||||
|
COS PB13 input/PD
|
||||||
|
|
||||||
|
DSTAR PB7 output
|
||||||
|
DMR PB6 output
|
||||||
|
YSF PB8 output
|
||||||
|
P25 PB9 output
|
||||||
|
NXDN PB10 output
|
||||||
|
POCSAG PB11 output
|
||||||
|
|
||||||
|
RX PB0 analog input (ADC1_8)
|
||||||
|
RSSI PB1 analog input (ADC2_9)
|
||||||
|
TX PA4 analog output (DAC_OUT1)
|
||||||
|
|
||||||
|
EXT_CLK PA15 input (AF: TIM2_CH1_ETR)
|
||||||
|
|
||||||
|
USART1_TXD PA9 output (AF)
|
||||||
|
USART1_RXD PA10 input (AF)
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PIN_PTT 12
|
||||||
|
#define PORT_PTT GPIOB
|
||||||
|
#define BB_PTT *((bitband_t)BITBAND_PERIPH(&PORT_PTT->ODR, PIN_PTT))
|
||||||
|
#define PIN_COSLED 5
|
||||||
|
#define PORT_COSLED GPIOB
|
||||||
|
#define BB_COSLED *((bitband_t)BITBAND_PERIPH(&PORT_COSLED->ODR, PIN_COSLED))
|
||||||
|
#define PIN_LED 4
|
||||||
|
#define PORT_LED GPIOB
|
||||||
|
#define BB_LED *((bitband_t)BITBAND_PERIPH(&PORT_LED->ODR, PIN_LED))
|
||||||
|
#define PIN_COS 13
|
||||||
|
#define PORT_COS GPIOB
|
||||||
|
#define BB_COS *((bitband_t)BITBAND_PERIPH(&PORT_COS->IDR, PIN_COS))
|
||||||
|
|
||||||
|
#define PIN_DSTAR 7
|
||||||
|
#define PORT_DSTAR GPIOB
|
||||||
|
#define BB_DSTAR *((bitband_t)BITBAND_PERIPH(&PORT_DSTAR->ODR, PIN_DSTAR))
|
||||||
|
#define PIN_DMR 6
|
||||||
|
#define PORT_DMR GPIOB
|
||||||
|
#define BB_DMR *((bitband_t)BITBAND_PERIPH(&PORT_DMR->ODR, PIN_DMR))
|
||||||
|
#define PIN_YSF 8
|
||||||
|
#define PORT_YSF GPIOB
|
||||||
|
#define BB_YSF *((bitband_t)BITBAND_PERIPH(&PORT_YSF->ODR, PIN_YSF))
|
||||||
|
#define PIN_P25 9
|
||||||
|
#define PORT_P25 GPIOB
|
||||||
|
#define BB_P25 *((bitband_t)BITBAND_PERIPH(&PORT_P25->ODR, PIN_P25))
|
||||||
|
#define PIN_NXDN 10
|
||||||
|
#define PORT_NXDN GPIOB
|
||||||
|
#define BB_NXDN *((bitband_t)BITBAND_PERIPH(&PORT_NXDN->ODR, PIN_NXDN))
|
||||||
|
#define PIN_POCSAG 11
|
||||||
|
#define PORT_POCSAG GPIOB
|
||||||
|
#define BB_POCSAG *((bitband_t)BITBAND_PERIPH(&PORT_POCSAG->ODR, PIN_POCSAG))
|
||||||
|
|
||||||
|
#define PIN_RX 0
|
||||||
|
#define PIN_RX_ADC_CH 8
|
||||||
|
#define PORT_RX GPIOB
|
||||||
|
#define PIN_RSSI 1
|
||||||
|
#define PIN_RSSI_ADC_CH 9
|
||||||
|
#define PORT_RSSI GPIOB
|
||||||
|
#define PIN_TX 4
|
||||||
|
#define PIN_TX_DAC_CH 1
|
||||||
|
#define PORT_TX GPIOA
|
||||||
|
|
||||||
|
#define PIN_EXT_CLK 15
|
||||||
|
#define SRC_EXT_CLK 15
|
||||||
|
#define PORT_EXT_CLK GPIOA
|
||||||
|
|
||||||
|
#define PIN_USART1_TXD 9
|
||||||
|
#define PORT_USART1_TXD GPIOA
|
||||||
|
#define PIN_USART1_RXD 10
|
||||||
|
#define PORT_USART1_RXD GPIOA
|
||||||
|
|
||||||
|
#else // defined(STM32F1_POG)
|
||||||
|
#error "Either STM32F1_POG, or sth need to be defined"
|
||||||
|
#endif // defined(STM32F1_POG)
|
||||||
|
|
||||||
|
const uint16_t DC_OFFSET = 2048U;
|
||||||
|
|
||||||
|
// Sampling frequency
|
||||||
|
#define SAMP_FREQ 48000
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
void TIM2_IRQHandler() {
|
||||||
|
if ((TIM2->SR & TIM_SR_UIF) == TIM_SR_UIF) {
|
||||||
|
TIM2->SR = ~TIM_SR_UIF; // clear UI flag
|
||||||
|
io.interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void delay(uint32_t cnt)
|
||||||
|
{
|
||||||
|
while(cnt--)
|
||||||
|
asm("nop");
|
||||||
|
}
|
||||||
|
|
||||||
|
// source: http://www.freddiechopin.info/
|
||||||
|
void GPIOConfigPin(GPIO_TypeDef *port_ptr, uint32_t pin, uint32_t mode_cnf_value)
|
||||||
|
{
|
||||||
|
volatile uint32_t *cr_ptr;
|
||||||
|
uint32_t cr_value;
|
||||||
|
|
||||||
|
cr_ptr = &port_ptr->CRL; // configuration of pins [0,7] is in CRL
|
||||||
|
|
||||||
|
if (pin >= 8) // is pin in [8; 15]?
|
||||||
|
{ // configuration of pins [8,15] is in CRH
|
||||||
|
cr_ptr++; // advance to next struct element CRL -> CRH
|
||||||
|
pin -= 8; // crop the pin number
|
||||||
|
}
|
||||||
|
|
||||||
|
cr_value = *cr_ptr; // localize the CRL / CRH value
|
||||||
|
|
||||||
|
cr_value &= ~(0xF << (pin * 4)); // clear the MODE and CNF fields (now that pin is an analog input)
|
||||||
|
cr_value |= (mode_cnf_value << (pin * 4)); // save new MODE and CNF value for desired pin
|
||||||
|
|
||||||
|
*cr_ptr = cr_value; // save localized value to CRL / CRL
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(STM32F1_POG)
|
||||||
|
void FancyLEDEffect()
|
||||||
|
{
|
||||||
|
bitband_t foo[] = {&BB_LED, &BB_COSLED, &BB_PTT, &BB_DMR, &BB_DSTAR, &BB_YSF, &BB_P25};
|
||||||
|
|
||||||
|
for(int i=0; i<7; i++){
|
||||||
|
*foo[i] = 0x01;
|
||||||
|
}
|
||||||
|
GPIOConfigPin(PORT_USART1_TXD, PIN_USART1_TXD, GPIO_CRL_MODE0_1);
|
||||||
|
*((bitband_t)BITBAND_PERIPH(&PORT_USART1_TXD->ODR, PIN_USART1_TXD)) = 0x00;
|
||||||
|
delay(SystemCoreClock/1000*100);
|
||||||
|
for(int i=0; i<7; i++){
|
||||||
|
*foo[i] = 0x00;
|
||||||
|
}
|
||||||
|
*((bitband_t)BITBAND_PERIPH(&PORT_USART1_TXD->ODR, PIN_USART1_TXD)) = 0x01;
|
||||||
|
delay(SystemCoreClock/1000*20);
|
||||||
|
*((bitband_t)BITBAND_PERIPH(&PORT_USART1_TXD->ODR, PIN_USART1_TXD)) = 0x00;
|
||||||
|
delay(SystemCoreClock/1000*10);
|
||||||
|
*((bitband_t)BITBAND_PERIPH(&PORT_USART1_TXD->ODR, PIN_USART1_TXD)) = 0x01;
|
||||||
|
|
||||||
|
*foo[0] = 0x01;
|
||||||
|
for(int i=1; i<7; i++){
|
||||||
|
delay(SystemCoreClock/1000*10);
|
||||||
|
*foo[i-1] = 0x00;
|
||||||
|
*foo[i] = 0x01;
|
||||||
|
}
|
||||||
|
for(int i=5; i>=0; i--){
|
||||||
|
delay(SystemCoreClock/1000*10);
|
||||||
|
*foo[i+1] = 0x00;
|
||||||
|
*foo[i] = 0x01;
|
||||||
|
}
|
||||||
|
delay(SystemCoreClock/1000*10);
|
||||||
|
*foo[5+1-6] = 0x00;
|
||||||
|
*((bitband_t)BITBAND_PERIPH(&PORT_USART1_TXD->ODR, PIN_USART1_TXD)) = 0x00;
|
||||||
|
delay(SystemCoreClock/1000*10);
|
||||||
|
*((bitband_t)BITBAND_PERIPH(&PORT_USART1_TXD->ODR, PIN_USART1_TXD)) = 0x01;
|
||||||
|
GPIOConfigPin(PORT_USART1_TXD, PIN_USART1_TXD, GPIO_CRL_MODE0_1|GPIO_CRL_CNF0_1);
|
||||||
|
delay(SystemCoreClock/1000*50);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline void GPIOInit()
|
||||||
|
{
|
||||||
|
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN
|
||||||
|
| RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN
|
||||||
|
| RCC_APB2ENR_AFIOEN; // enable all GPIOs
|
||||||
|
|
||||||
|
// set all ports to input with pull-down
|
||||||
|
GPIOA->CRL = 0x88888888;
|
||||||
|
GPIOA->CRH = 0x88888888;
|
||||||
|
GPIOA->ODR = 0;
|
||||||
|
GPIOB->CRL = 0x88888888;
|
||||||
|
GPIOB->CRH = 0x88888888;
|
||||||
|
GPIOB->ODR = 0;
|
||||||
|
GPIOC->CRL = 0x88888888;
|
||||||
|
GPIOC->CRH = 0x88888888;
|
||||||
|
GPIOC->ODR = 0;
|
||||||
|
GPIOD->CRL = 0x88888888;
|
||||||
|
GPIOD->CRH = 0x88888888;
|
||||||
|
GPIOD->ODR = 0;
|
||||||
|
|
||||||
|
// configure ports
|
||||||
|
GPIOConfigPin(PORT_PTT, PIN_PTT, GPIO_CRL_MODE0_1);
|
||||||
|
GPIOConfigPin(PORT_COSLED, PIN_COSLED, GPIO_CRL_MODE0_1);
|
||||||
|
GPIOConfigPin(PORT_LED, PIN_LED, GPIO_CRL_MODE0_1);
|
||||||
|
GPIOConfigPin(PORT_COS, PIN_COS, GPIO_CRL_CNF0_1);
|
||||||
|
|
||||||
|
GPIOConfigPin(PORT_DSTAR, PIN_DSTAR, GPIO_CRL_MODE0_1);
|
||||||
|
GPIOConfigPin(PORT_DMR, PIN_DMR, GPIO_CRL_MODE0_1);
|
||||||
|
GPIOConfigPin(PORT_YSF, PIN_YSF, GPIO_CRL_MODE0_1);
|
||||||
|
GPIOConfigPin(PORT_P25, PIN_P25, GPIO_CRL_MODE0_1);
|
||||||
|
#if !defined(USE_ALTERNATE_NXDN_LEDS)
|
||||||
|
GPIOConfigPin(PORT_NXDN, PIN_NXDN, GPIO_CRL_MODE0_1);
|
||||||
|
#endif
|
||||||
|
#if !defined(USE_ALTERNATE_POCSAG_LEDS)
|
||||||
|
GPIOConfigPin(PORT_POCSAG, PIN_POCSAG, GPIO_CRL_MODE0_1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GPIOConfigPin(PORT_RX, PIN_RX, 0);
|
||||||
|
#if defined(SEND_RSSI_DATA)
|
||||||
|
GPIOConfigPin(PORT_RSSI, PIN_RSSI, 0);
|
||||||
|
#endif
|
||||||
|
GPIOConfigPin(PORT_TX, PIN_TX, 0);
|
||||||
|
|
||||||
|
#if defined(EXTERNAL_OSC)
|
||||||
|
#if defined(STM32F1_POG)
|
||||||
|
GPIOConfigPin(PORT_EXT_CLK, PIN_EXT_CLK, GPIO_CRL_CNF0_0);
|
||||||
|
AFIO->MAPR = (AFIO->MAPR & ~AFIO_MAPR_TIM2_REMAP) | AFIO_MAPR_TIM2_REMAP_0;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GPIOConfigPin(PORT_USART1_TXD, PIN_USART1_TXD, GPIO_CRL_MODE0_1|GPIO_CRL_CNF0_1);
|
||||||
|
GPIOConfigPin(PORT_USART1_RXD, PIN_USART1_RXD, GPIO_CRL_CNF0_0);
|
||||||
|
|
||||||
|
AFIO->MAPR = (AFIO->MAPR & ~AFIO_MAPR_SWJ_CFG) | AFIO_MAPR_SWJ_CFG_1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void ADCInit()
|
||||||
|
{
|
||||||
|
RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_ADCPRE_Msk)
|
||||||
|
| RCC_CFGR_ADCPRE_DIV6; // ADC clock divided by 6 (72MHz/6 = 12MHz)
|
||||||
|
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
|
||||||
|
#if defined(SEND_RSSI_DATA)
|
||||||
|
RCC->APB2ENR |= RCC_APB2ENR_ADC2EN;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Init ADCs in dual mode (RSSI)
|
||||||
|
#if defined(SEND_RSSI_DATA)
|
||||||
|
ADC1->CR1 = ADC_CR1_DUALMOD_1|ADC_CR1_DUALMOD_2; // Regular simultaneous mode
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Set sampling time to 7.5 cycles
|
||||||
|
if (PIN_RX_ADC_CH < 10) {
|
||||||
|
ADC1->SMPR2 = ADC_SMPR2_SMP0_0 << (3*PIN_RX_ADC_CH);
|
||||||
|
} else {
|
||||||
|
ADC1->SMPR1 = ADC_SMPR1_SMP10_0 << (3*PIN_RX_ADC_CH);
|
||||||
|
}
|
||||||
|
#if defined(SEND_RSSI_DATA)
|
||||||
|
if (PIN_RSSI_ADC_CH < 10) {
|
||||||
|
ADC2->SMPR2 = ADC_SMPR2_SMP0_0 << (3*PIN_RSSI_ADC_CH);
|
||||||
|
} else {
|
||||||
|
ADC2->SMPR1 = ADC_SMPR1_SMP10_0 << (3*PIN_RSSI_ADC_CH);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Set conversion channel (single conversion)
|
||||||
|
ADC1->SQR3 = PIN_RX_ADC_CH;
|
||||||
|
#if defined(SEND_RSSI_DATA)
|
||||||
|
ADC2->SQR3 = PIN_RSSI_ADC_CH;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Enable ADC
|
||||||
|
ADC1->CR2 |= ADC_CR2_ADON;
|
||||||
|
|
||||||
|
#if defined(SEND_RSSI_DATA)
|
||||||
|
// Enable ADC2
|
||||||
|
ADC2->CR2 |= ADC_CR2_ADON;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Start calibration
|
||||||
|
delay(6*2);
|
||||||
|
ADC1->CR2 |= ADC_CR2_CAL;
|
||||||
|
while((ADC1->CR2 & ADC_CR2_CAL) == ADC_CR2_CAL)
|
||||||
|
;
|
||||||
|
#if defined(SEND_RSSI_DATA)
|
||||||
|
ADC2->CR2 |= ADC_CR2_CAL;
|
||||||
|
while((ADC2->CR2 & ADC_CR2_CAL) == ADC_CR2_CAL)
|
||||||
|
;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Trigger first conversion
|
||||||
|
ADC1->CR2 |= ADC_CR2_ADON;
|
||||||
|
#if defined(SEND_RSSI_DATA)
|
||||||
|
ADC2->CR2 |= ADC_CR2_ADON;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void DACInit()
|
||||||
|
{
|
||||||
|
RCC->APB1ENR |= RCC_APB1ENR_DACEN;
|
||||||
|
|
||||||
|
DAC->CR = DAC_CR_EN1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void TimerInit()
|
||||||
|
{
|
||||||
|
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
|
||||||
|
|
||||||
|
#if defined(EXTERNAL_OSC)
|
||||||
|
// Enable external clock, prescaler /4
|
||||||
|
TIM2->SMCR = TIM_SMCR_ECE | TIM_SMCR_ETPS_1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TIM2 output frequency
|
||||||
|
TIM2->PSC = 0;
|
||||||
|
#if defined(EXTERNAL_OSC)
|
||||||
|
// TimerCount = ExternalOsc
|
||||||
|
// /4 (external clock prescaler)
|
||||||
|
// /SAMP_FREQ
|
||||||
|
TIM2->ARR = (uint16_t) ((EXTERNAL_OSC/(4*SAMP_FREQ)) - 1);
|
||||||
|
#else
|
||||||
|
TIM2->ARR = (uint16_t) ((SystemCoreClock/(SAMP_FREQ)) - 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Enable TIse 1%-tolerance comM2 interrupt
|
||||||
|
TIM2->DIER = TIM_DIER_UIE;
|
||||||
|
NVIC_EnableIRQ(TIM2_IRQn);
|
||||||
|
|
||||||
|
// Enable TIM2
|
||||||
|
TIM2->CR1 |= TIM_CR1_CEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CIO::initInt()
|
||||||
|
{
|
||||||
|
GPIOInit();
|
||||||
|
ADCInit();
|
||||||
|
DACInit();
|
||||||
|
#if defined(STM32F1_POG)
|
||||||
|
FancyLEDEffect();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIO::startInt()
|
||||||
|
{
|
||||||
|
TimerInit();
|
||||||
|
|
||||||
|
BB_COSLED = 0;
|
||||||
|
BB_LED = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIO::interrupt()
|
||||||
|
{
|
||||||
|
uint8_t control = MARK_NONE;
|
||||||
|
uint16_t sample = DC_OFFSET;
|
||||||
|
uint16_t rawRSSI = 0U;
|
||||||
|
bitband_t eoc = (bitband_t)BITBAND_PERIPH(&ADC1->SR, ADC_SR_EOS_Pos);
|
||||||
|
bitband_t adon = (bitband_t)BITBAND_PERIPH(&ADC1->CR2, ADC_CR2_ADON_Pos);
|
||||||
|
#if defined(SEND_RSSI_DATA)
|
||||||
|
bitband_t rssi_adon = (bitband_t)BITBAND_PERIPH(&ADC2->CR2, ADC_CR2_ADON_Pos);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (*eoc) {
|
||||||
|
// trigger next conversion
|
||||||
|
*adon = 1;
|
||||||
|
#if defined(SEND_RSSI_DATA)
|
||||||
|
*rssi_adon = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_txBuffer.get(sample, control);
|
||||||
|
DAC->DHR12R1 = sample; // Send the value to the DAC
|
||||||
|
|
||||||
|
// Read value from ADC1 and ADC2
|
||||||
|
sample = ADC1->DR; // read conversion result; EOC is cleared by this read
|
||||||
|
m_rxBuffer.put(sample, control);
|
||||||
|
#if defined(SEND_RSSI_DATA)
|
||||||
|
rawRSSI = ADC2->DR;
|
||||||
|
m_rssiBuffer.put(rawRSSI);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_watchdog++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CIO::getCOSInt()
|
||||||
|
{
|
||||||
|
return BB_COS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIO::setLEDInt(bool on)
|
||||||
|
{
|
||||||
|
BB_LED = !!on;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIO::setPTTInt(bool on)
|
||||||
|
{
|
||||||
|
BB_PTT = !!on;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIO::setCOSInt(bool on)
|
||||||
|
{
|
||||||
|
BB_COSLED = !!on;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIO::setDStarInt(bool on)
|
||||||
|
{
|
||||||
|
BB_DSTAR = !!on;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIO::setDMRInt(bool on)
|
||||||
|
{
|
||||||
|
BB_DMR = !!on;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIO::setYSFInt(bool on)
|
||||||
|
{
|
||||||
|
BB_YSF = !!on;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIO::setP25Int(bool on)
|
||||||
|
{
|
||||||
|
BB_P25 = !!on;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIO::setNXDNInt(bool on)
|
||||||
|
{
|
||||||
|
#if defined(USE_ALTERNATE_NXDN_LEDS)
|
||||||
|
BB_YSF = !!on;
|
||||||
|
BB_P25 = !!on;
|
||||||
|
#else
|
||||||
|
BB_NXDN = !!on;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIO::setPOCSAGInt(bool on)
|
||||||
|
{
|
||||||
|
#if defined(USE_ALTERNATE_POCSAG_LEDS)
|
||||||
|
BB_DSTAR = !!on;
|
||||||
|
BB_DMR = !!on;
|
||||||
|
#else
|
||||||
|
BB_POCSAG = !!on;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIO::delayInt(unsigned int dly)
|
||||||
|
{
|
||||||
|
delay(dly);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
+71
-47
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2016,2017,2018 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -34,8 +34,15 @@
|
|||||||
#define PIN_DMR 10
|
#define PIN_DMR 10
|
||||||
#define PIN_YSF 11
|
#define PIN_YSF 11
|
||||||
#define PIN_P25 12
|
#define PIN_P25 12
|
||||||
#define PIN_ADC 5 // A0, Pin 14
|
#if defined(__MK20DX256__)
|
||||||
#define PIN_RSSI 8 // A2, Pin 16
|
#define PIN_NXDN 2
|
||||||
|
#define PIN_POCSAG 3
|
||||||
|
#else
|
||||||
|
#define PIN_NXDN 24
|
||||||
|
#define PIN_POCSAG 25
|
||||||
|
#endif
|
||||||
|
#define PIN_ADC 5 // A0, Pin 14
|
||||||
|
#define PIN_RSSI 4 // Teensy 3.5/3.6, A16, Pin 35. Teensy 3.1/3.2, A17, Pin 28
|
||||||
|
|
||||||
#define PDB_CHnC1_TOS 0x0100
|
#define PDB_CHnC1_TOS 0x0100
|
||||||
#define PDB_CHnC1_EN 0x0001
|
#define PDB_CHnC1_EN 0x0001
|
||||||
@@ -45,15 +52,8 @@ const uint16_t DC_OFFSET = 2048U;
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
void adc0_isr()
|
void adc0_isr()
|
||||||
{
|
{
|
||||||
io.interrupt(0U);
|
io.interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(SEND_RSSI_DATA)
|
|
||||||
void adc1_isr()
|
|
||||||
{
|
|
||||||
io.interrupt(1U);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CIO::initInt()
|
void CIO::initInt()
|
||||||
@@ -64,12 +64,18 @@ void CIO::initInt()
|
|||||||
pinMode(PIN_LED, OUTPUT);
|
pinMode(PIN_LED, OUTPUT);
|
||||||
pinMode(PIN_COS, INPUT);
|
pinMode(PIN_COS, INPUT);
|
||||||
|
|
||||||
#if defined(ARDUINO_MODE_PINS)
|
#if defined(MODE_LEDS)
|
||||||
// Set up the mode output pins
|
// Set up the mode output pins
|
||||||
pinMode(PIN_DSTAR, OUTPUT);
|
pinMode(PIN_DSTAR, OUTPUT);
|
||||||
pinMode(PIN_DMR, OUTPUT);
|
pinMode(PIN_DMR, OUTPUT);
|
||||||
pinMode(PIN_YSF, OUTPUT);
|
pinMode(PIN_YSF, OUTPUT);
|
||||||
pinMode(PIN_P25, OUTPUT);
|
pinMode(PIN_P25, OUTPUT);
|
||||||
|
#if !defined(USE_ALTERNATE_NXDN_LEDS)
|
||||||
|
pinMode(PIN_NXDN, OUTPUT);
|
||||||
|
#endif
|
||||||
|
#if !defined(USE_ALTERNATE_POCSAG_LEDS)
|
||||||
|
pinMode(PIN_POCSAG, OUTPUT);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,17 +83,17 @@ void CIO::startInt()
|
|||||||
{
|
{
|
||||||
// Initialise the DAC
|
// Initialise the DAC
|
||||||
SIM_SCGC2 |= SIM_SCGC2_DAC0;
|
SIM_SCGC2 |= SIM_SCGC2_DAC0;
|
||||||
DAC0_C0 = DAC_C0_DACEN | DAC_C0_DACRFS; // 1.2V VDDA is DACREF_2
|
DAC0_C0 = DAC_C0_DACEN | DAC_C0_DACRFS; // 3.3V VDDA is DACREF_2
|
||||||
|
|
||||||
// Initialise ADC0
|
// Initialise ADC0
|
||||||
SIM_SCGC6 |= SIM_SCGC6_ADC0;
|
SIM_SCGC6 |= SIM_SCGC6_ADC0;
|
||||||
ADC0_CFG1 = ADC_CFG1_ADIV(1) | ADC_CFG1_ADICLK(1) | // Single-ended 12 bits, long sample time
|
ADC0_CFG1 = ADC_CFG1_ADIV(1) | ADC_CFG1_ADICLK(1) | // Single-ended 12 bits, long sample time
|
||||||
ADC_CFG1_MODE(1) | ADC_CFG1_ADLSMP;
|
ADC_CFG1_MODE(1) | ADC_CFG1_ADLSMP;
|
||||||
ADC0_CFG2 = ADC_CFG2_MUXSEL | ADC_CFG2_ADLSTS(2); // Select channels ADxxxb
|
ADC0_CFG2 = ADC_CFG2_MUXSEL | ADC_CFG2_ADLSTS(2); // Select channels ADxxxb
|
||||||
ADC0_SC2 = ADC_SC2_REFSEL(1) | ADC_SC2_ADTRG; // Voltage ref internal, hardware trigger
|
ADC0_SC2 = ADC_SC2_REFSEL(0) | ADC_SC2_ADTRG; // Voltage ref external, hardware trigger
|
||||||
ADC0_SC3 = ADC_SC3_AVGE | ADC_SC3_AVGS(0); // Enable averaging, 4 samples
|
ADC0_SC3 = ADC_SC3_AVGE | ADC_SC3_AVGS(0); // Enable averaging, 4 samples
|
||||||
|
|
||||||
ADC0_SC3 = ADC_SC3_CAL;
|
ADC0_SC3 |= ADC_SC3_CAL;
|
||||||
while (ADC0_SC3 & ADC_SC3_CAL) // Wait for calibration
|
while (ADC0_SC3 & ADC_SC3_CAL) // Wait for calibration
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -105,10 +111,10 @@ void CIO::startInt()
|
|||||||
ADC1_CFG1 = ADC_CFG1_ADIV(1) | ADC_CFG1_ADICLK(1) | // Single-ended 12 bits, long sample time
|
ADC1_CFG1 = ADC_CFG1_ADIV(1) | ADC_CFG1_ADICLK(1) | // Single-ended 12 bits, long sample time
|
||||||
ADC_CFG1_MODE(1) | ADC_CFG1_ADLSMP;
|
ADC_CFG1_MODE(1) | ADC_CFG1_ADLSMP;
|
||||||
ADC1_CFG2 = ADC_CFG2_MUXSEL | ADC_CFG2_ADLSTS(2); // Select channels ADxxxb
|
ADC1_CFG2 = ADC_CFG2_MUXSEL | ADC_CFG2_ADLSTS(2); // Select channels ADxxxb
|
||||||
ADC1_SC2 = ADC_SC2_REFSEL(1); // Voltage ref internal, software trigger
|
ADC1_SC2 = ADC_SC2_REFSEL(0); // Voltage ref external, software trigger
|
||||||
ADC1_SC3 = ADC_SC3_AVGE | ADC_SC3_AVGS(0); // Enable averaging, 4 samples
|
ADC1_SC3 = ADC_SC3_AVGE | ADC_SC3_AVGS(0); // Enable averaging, 4 samples
|
||||||
|
|
||||||
ADC1_SC3 = ADC_SC3_CAL;
|
ADC1_SC3 |= ADC_SC3_CAL;
|
||||||
while (ADC1_SC3 & ADC_SC3_CAL) // Wait for calibration
|
while (ADC1_SC3 & ADC_SC3_CAL) // Wait for calibration
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -116,14 +122,11 @@ void CIO::startInt()
|
|||||||
ADC1_CLP2 + ADC1_CLP1 + ADC1_CLP0;
|
ADC1_CLP2 + ADC1_CLP1 + ADC1_CLP0;
|
||||||
sum1 = (sum1 / 2U) | 0x8000U;
|
sum1 = (sum1 / 2U) | 0x8000U;
|
||||||
ADC1_PG = sum1;
|
ADC1_PG = sum1;
|
||||||
|
|
||||||
NVIC_ENABLE_IRQ(IRQ_ADC1);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(EXTERNAL_OSC)
|
#if defined(EXTERNAL_OSC)
|
||||||
// Set ADC0 to trigger from the LPTMR at 24 kHz
|
// Set ADC0 to trigger from the LPTMR at 48 kHz
|
||||||
SIM_SOPT7 = SIM_SOPT7_ADC0ALTTRGEN | // Enable ADC0 alternate trigger
|
SIM_SOPT7 = SIM_SOPT7_ADC0ALTTRGEN | // Enable ADC0 alternate trigger
|
||||||
SIM_SOPT7_ADC0PRETRGSEL | // Enable ADC0 pre-trigger
|
|
||||||
SIM_SOPT7_ADC0TRGSEL(14); // Trigger ADC0 by LPTMR0
|
SIM_SOPT7_ADC0TRGSEL(14); // Trigger ADC0 by LPTMR0
|
||||||
|
|
||||||
CORE_PIN13_CONFIG = PORT_PCR_MUX(3);
|
CORE_PIN13_CONFIG = PORT_PCR_MUX(3);
|
||||||
@@ -131,14 +134,14 @@ void CIO::startInt()
|
|||||||
SIM_SCGC5 |= SIM_SCGC5_LPTIMER; // Enable Low Power Timer Access
|
SIM_SCGC5 |= SIM_SCGC5_LPTIMER; // Enable Low Power Timer Access
|
||||||
LPTMR0_CSR = 0; // Disable
|
LPTMR0_CSR = 0; // Disable
|
||||||
LPTMR0_PSR = LPTMR_PSR_PBYP; // Bypass prescaler/filter
|
LPTMR0_PSR = LPTMR_PSR_PBYP; // Bypass prescaler/filter
|
||||||
LPTMR0_CMR = (EXTERNAL_OSC / 24000) - 1; // Frequency divided by CMR + 1
|
LPTMR0_CMR = (EXTERNAL_OSC / 48000) - 1; // Frequency divided by CMR + 1
|
||||||
LPTMR0_CSR = LPTMR_CSR_TPS(2) | // Pin: 0=CMP0, 1=xtal, 2=pin13
|
LPTMR0_CSR = LPTMR_CSR_TPS(2) | // Pin: 0=CMP0, 1=xtal, 2=pin13
|
||||||
LPTMR_CSR_TMS; // Mode Select, 0=timer, 1=counter
|
LPTMR_CSR_TMS; // Mode Select, 0=timer, 1=counter
|
||||||
LPTMR0_CSR |= LPTMR_CSR_TEN; // Enable
|
LPTMR0_CSR |= LPTMR_CSR_TEN; // Enable
|
||||||
#else
|
#else
|
||||||
// Setup PDB for ADC0 at 24 kHz
|
// Setup PDB for ADC0 at 48 kHz
|
||||||
SIM_SCGC6 |= SIM_SCGC6_PDB; // Enable PDB clock
|
SIM_SCGC6 |= SIM_SCGC6_PDB; // Enable PDB clock
|
||||||
PDB0_MOD = (F_BUS / 24000) - 1; // Timer period - 1
|
PDB0_MOD = (F_BUS / 48000) - 1; // Timer period - 1
|
||||||
PDB0_IDLY = 0; // Interrupt delay
|
PDB0_IDLY = 0; // Interrupt delay
|
||||||
PDB0_CH0C1 = PDB_CHnC1_TOS | PDB_CHnC1_EN; // Enable pre-trigger for ADC0
|
PDB0_CH0C1 = PDB_CHnC1_TOS | PDB_CHnC1_EN; // Enable pre-trigger for ADC0
|
||||||
PDB0_SC = PDB_SC_TRGSEL(15) | PDB_SC_PDBEN | // SW trigger, enable interrupts, continuous mode
|
PDB0_SC = PDB_SC_TRGSEL(15) | PDB_SC_PDBEN | // SW trigger, enable interrupts, continuous mode
|
||||||
@@ -151,37 +154,33 @@ void CIO::startInt()
|
|||||||
digitalWrite(PIN_LED, HIGH);
|
digitalWrite(PIN_LED, HIGH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CIO::interrupt(uint8_t source)
|
void CIO::interrupt()
|
||||||
{
|
{
|
||||||
if (source == 0U) { // ADC0
|
uint8_t control = MARK_NONE;
|
||||||
uint8_t control = MARK_NONE;
|
uint16_t sample = DC_OFFSET;
|
||||||
uint16_t sample = DC_OFFSET;
|
|
||||||
|
|
||||||
m_txBuffer.get(sample, control);
|
m_txBuffer.get(sample, control);
|
||||||
*(int16_t *)&(DAC0_DAT0L) = sample;
|
*(int16_t *)&(DAC0_DAT0L) = sample;
|
||||||
|
|
||||||
if ((ADC0_SC1A & ADC_SC1_COCO) == ADC_SC1_COCO) {
|
if ((ADC0_SC1A & ADC_SC1_COCO) == ADC_SC1_COCO) {
|
||||||
sample = ADC0_RA;
|
sample = ADC0_RA;
|
||||||
m_rxBuffer.put(sample, control);
|
m_rxBuffer.put(sample, control);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(SEND_RSSI_DATA)
|
#if defined(SEND_RSSI_DATA)
|
||||||
ADC1_SC1A = ADC_SC1_AIEN | PIN_RSSI;
|
if ((ADC1_SC1A & ADC_SC1_COCO) == ADC_SC1_COCO) {
|
||||||
|
uint16_t rssi = ADC1_RA;
|
||||||
|
m_rssiBuffer.put(rssi);
|
||||||
|
} else {
|
||||||
|
m_rssiBuffer.put(0U);
|
||||||
|
}
|
||||||
|
|
||||||
|
ADC1_SC1A = PIN_RSSI; // Start the next RSSI conversion
|
||||||
#else
|
#else
|
||||||
m_rssiBuffer.put(0U);
|
m_rssiBuffer.put(0U);
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
m_watchdog++;
|
m_watchdog++;
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(SEND_RSSI_DATA)
|
|
||||||
if (source == 1U) { // ADC1
|
|
||||||
if ((ADC1_SC1A & ADC_SC1_COCO) == ADC_SC1_COCO) {
|
|
||||||
uint16_t rssi = ADC1_RA;
|
|
||||||
m_rssiBuffer.put(rssi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CIO::getCOSInt()
|
bool CIO::getCOSInt()
|
||||||
@@ -224,4 +223,29 @@ void CIO::setP25Int(bool on)
|
|||||||
digitalWrite(PIN_P25, on ? HIGH : LOW);
|
digitalWrite(PIN_P25, on ? HIGH : LOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CIO::setNXDNInt(bool on)
|
||||||
|
{
|
||||||
|
#if defined(USE_ALTERNATE_NXDN_LEDS)
|
||||||
|
digitalWrite(PIN_YSF, on ? HIGH : LOW);
|
||||||
|
digitalWrite(PIN_P25, on ? HIGH : LOW);
|
||||||
|
#else
|
||||||
|
digitalWrite(PIN_NXDN, on ? HIGH : LOW);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIO::setPOCSAGInt(bool on)
|
||||||
|
{
|
||||||
|
#if defined(USE_ALTERNATE_POCSAG_LEDS)
|
||||||
|
digitalWrite(PIN_DSTAR, on ? HIGH : LOW);
|
||||||
|
digitalWrite(PIN_DMR, on ? HIGH : LOW);
|
||||||
|
#else
|
||||||
|
digitalWrite(PIN_POCSAG, on ? HIGH : LOW);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIO::delayInt(unsigned int dly)
|
||||||
|
{
|
||||||
|
delay(dly);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
|
||||||
* Copyright (C) 2016 by Mathis Schmieder DB9MAT
|
* Copyright (C) 2016 by Mathis Schmieder DB9MAT
|
||||||
* Copyright (C) 2016 by Colin Durbridge G4EML
|
* Copyright (C) 2016 by Colin Durbridge G4EML
|
||||||
*
|
*
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(STM32F4XX) || defined(STM32F4)
|
#if defined(STM32F4XX) || defined(STM32F7XX) || defined(STM32F105xC)
|
||||||
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
@@ -26,19 +26,18 @@
|
|||||||
// Global variables
|
// Global variables
|
||||||
MMDVM_STATE m_modemState = STATE_IDLE;
|
MMDVM_STATE m_modemState = STATE_IDLE;
|
||||||
|
|
||||||
bool m_dstarEnable = true;
|
bool m_dstarEnable = true;
|
||||||
bool m_dmrEnable = true;
|
bool m_dmrEnable = true;
|
||||||
bool m_ysfEnable = true;
|
bool m_ysfEnable = true;
|
||||||
bool m_p25Enable = true;
|
bool m_p25Enable = true;
|
||||||
|
bool m_nxdnEnable = true;
|
||||||
|
bool m_pocsagEnable = true;
|
||||||
|
|
||||||
bool m_duplex = true;
|
bool m_duplex = true;
|
||||||
|
|
||||||
bool m_tx = false;
|
bool m_tx = false;
|
||||||
bool m_dcd = false;
|
bool m_dcd = false;
|
||||||
|
|
||||||
uint32_t m_sampleCount = 0U;
|
|
||||||
bool m_sampleInsert = false;
|
|
||||||
|
|
||||||
CDStarRX dstarRX;
|
CDStarRX dstarRX;
|
||||||
CDStarTX dstarTX;
|
CDStarTX dstarTX;
|
||||||
|
|
||||||
@@ -55,9 +54,17 @@ CYSFTX ysfTX;
|
|||||||
CP25RX p25RX;
|
CP25RX p25RX;
|
||||||
CP25TX p25TX;
|
CP25TX p25TX;
|
||||||
|
|
||||||
|
CNXDNRX nxdnRX;
|
||||||
|
CNXDNTX nxdnTX;
|
||||||
|
|
||||||
|
CPOCSAGTX pocsagTX;
|
||||||
|
|
||||||
CCalDStarRX calDStarRX;
|
CCalDStarRX calDStarRX;
|
||||||
CCalDStarTX calDStarTX;
|
CCalDStarTX calDStarTX;
|
||||||
CCalDMR calDMR;
|
CCalDMR calDMR;
|
||||||
|
CCalP25 calP25;
|
||||||
|
CCalNXDN calNXDN;
|
||||||
|
CCalRSSI calRSSI;
|
||||||
|
|
||||||
CCWIdTX cwIdTX;
|
CCWIdTX cwIdTX;
|
||||||
|
|
||||||
@@ -92,14 +99,26 @@ void loop()
|
|||||||
if (m_p25Enable && m_modemState == STATE_P25)
|
if (m_p25Enable && m_modemState == STATE_P25)
|
||||||
p25TX.process();
|
p25TX.process();
|
||||||
|
|
||||||
|
if (m_nxdnEnable && m_modemState == STATE_NXDN)
|
||||||
|
nxdnTX.process();
|
||||||
|
|
||||||
|
if (m_pocsagEnable && (m_modemState == STATE_POCSAG || pocsagTX.busy()))
|
||||||
|
pocsagTX.process();
|
||||||
|
|
||||||
if (m_modemState == STATE_DSTARCAL)
|
if (m_modemState == STATE_DSTARCAL)
|
||||||
calDStarTX.process();
|
calDStarTX.process();
|
||||||
|
|
||||||
if (m_modemState == STATE_DMRCAL)
|
if (m_modemState == STATE_DMRCAL || m_modemState == STATE_LFCAL || m_modemState == STATE_DMRCAL1K || m_modemState == STATE_DMRDMO1K)
|
||||||
calDMR.process();
|
calDMR.process();
|
||||||
|
|
||||||
if (m_modemState == STATE_IDLE)
|
if (m_modemState == STATE_P25CAL1K)
|
||||||
cwIdTX.process();
|
calP25.process();
|
||||||
|
|
||||||
|
if (m_modemState == STATE_NXDNCAL1K)
|
||||||
|
calNXDN.process();
|
||||||
|
|
||||||
|
if (m_modemState == STATE_IDLE)
|
||||||
|
cwIdTX.process();
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
@@ -111,4 +130,3 @@ int main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
|
||||||
* Copyright (C) 2016 by Colin Durbridge G4EML
|
* Copyright (C) 2016 by Colin Durbridge G4EML
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@@ -23,19 +23,18 @@
|
|||||||
// Global variables
|
// Global variables
|
||||||
MMDVM_STATE m_modemState = STATE_IDLE;
|
MMDVM_STATE m_modemState = STATE_IDLE;
|
||||||
|
|
||||||
bool m_dstarEnable = true;
|
bool m_dstarEnable = true;
|
||||||
bool m_dmrEnable = true;
|
bool m_dmrEnable = true;
|
||||||
bool m_ysfEnable = true;
|
bool m_ysfEnable = true;
|
||||||
bool m_p25Enable = true;
|
bool m_p25Enable = true;
|
||||||
|
bool m_nxdnEnable = true;
|
||||||
|
bool m_pocsagEnable = true;
|
||||||
|
|
||||||
bool m_duplex = true;
|
bool m_duplex = true;
|
||||||
|
|
||||||
bool m_tx = false;
|
bool m_tx = false;
|
||||||
bool m_dcd = false;
|
bool m_dcd = false;
|
||||||
|
|
||||||
uint32_t m_sampleCount = 0U;
|
|
||||||
bool m_sampleInsert = false;
|
|
||||||
|
|
||||||
CDStarRX dstarRX;
|
CDStarRX dstarRX;
|
||||||
CDStarTX dstarTX;
|
CDStarTX dstarTX;
|
||||||
|
|
||||||
@@ -52,9 +51,17 @@ CYSFTX ysfTX;
|
|||||||
CP25RX p25RX;
|
CP25RX p25RX;
|
||||||
CP25TX p25TX;
|
CP25TX p25TX;
|
||||||
|
|
||||||
|
CNXDNRX nxdnRX;
|
||||||
|
CNXDNTX nxdnTX;
|
||||||
|
|
||||||
|
CPOCSAGTX pocsagTX;
|
||||||
|
|
||||||
CCalDStarRX calDStarRX;
|
CCalDStarRX calDStarRX;
|
||||||
CCalDStarTX calDStarTX;
|
CCalDStarTX calDStarTX;
|
||||||
CCalDMR calDMR;
|
CCalDMR calDMR;
|
||||||
|
CCalP25 calP25;
|
||||||
|
CCalNXDN calNXDN;
|
||||||
|
CCalRSSI calRSSI;
|
||||||
|
|
||||||
CCWIdTX cwIdTX;
|
CCWIdTX cwIdTX;
|
||||||
|
|
||||||
@@ -89,12 +96,24 @@ void loop()
|
|||||||
if (m_p25Enable && m_modemState == STATE_P25)
|
if (m_p25Enable && m_modemState == STATE_P25)
|
||||||
p25TX.process();
|
p25TX.process();
|
||||||
|
|
||||||
|
if (m_nxdnEnable && m_modemState == STATE_NXDN)
|
||||||
|
nxdnTX.process();
|
||||||
|
|
||||||
|
if (m_pocsagEnable && (m_modemState == STATE_POCSAG || pocsagTX.busy()))
|
||||||
|
pocsagTX.process();
|
||||||
|
|
||||||
if (m_modemState == STATE_DSTARCAL)
|
if (m_modemState == STATE_DSTARCAL)
|
||||||
calDStarTX.process();
|
calDStarTX.process();
|
||||||
|
|
||||||
if (m_modemState == STATE_DMRCAL)
|
if (m_modemState == STATE_DMRCAL || m_modemState == STATE_LFCAL || m_modemState == STATE_DMRCAL1K || m_modemState == STATE_DMRDMO1K)
|
||||||
calDMR.process();
|
calDMR.process();
|
||||||
|
|
||||||
|
if (m_modemState == STATE_P25CAL1K)
|
||||||
|
calP25.process();
|
||||||
|
|
||||||
|
if (m_modemState == STATE_NXDNCAL1K)
|
||||||
|
calNXDN.process();
|
||||||
|
|
||||||
if (m_modemState == STATE_IDLE)
|
if (m_modemState == STATE_IDLE)
|
||||||
cwIdTX.process();
|
cwIdTX.process();
|
||||||
}
|
}
|
||||||
|
|||||||
+39
-17
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<Project version="2G - 1.7.8" name="MMDVM_STM32F4xx">
|
<Project version="2G - 2.0.5" name="MMDVM_STM32F4xx">
|
||||||
<Target name="MMDVM_Discovery_407" isCurrent="1">
|
<Target name="MMDVM_Discovery_407" isCurrent="0">
|
||||||
<Device manufacturerId="9" manufacturerName="ST" chipId="344" chipName="STM32F407VG" boardId="" boardName=""/>
|
<Device manufacturerId="9" manufacturerName="ST" chipId="261" chipName="STM32F407VG" boardId="" boardName="" boardUrl="" coreId="" coreName=""/>
|
||||||
<BuildOption>
|
<BuildOption>
|
||||||
<Compile>
|
<Compile>
|
||||||
<Option name="OptimizationLevel" value="4"/>
|
<Option name="OptimizationLevel" value="4"/>
|
||||||
@@ -9,6 +9,8 @@
|
|||||||
<Option name="UserEditCompiler" value=""/>
|
<Option name="UserEditCompiler" value=""/>
|
||||||
<Option name="SupportCPlusplus" value="1"/>
|
<Option name="SupportCPlusplus" value="1"/>
|
||||||
<Option name="FPU" value="2"/>
|
<Option name="FPU" value="2"/>
|
||||||
|
<Option name="DEBUG" value="2"/>
|
||||||
|
<Option name="WARNING" value="1"/>
|
||||||
<Includepaths>
|
<Includepaths>
|
||||||
<Includepath path="."/>
|
<Includepath path="."/>
|
||||||
</Includepaths>
|
</Includepaths>
|
||||||
@@ -77,7 +79,7 @@
|
|||||||
<ExcludeFile/>
|
<ExcludeFile/>
|
||||||
</Target>
|
</Target>
|
||||||
<Target name="MMDVM_Pi_446" isCurrent="0">
|
<Target name="MMDVM_Pi_446" isCurrent="0">
|
||||||
<Device manufacturerId="9" manufacturerName="ST" chipId="344" chipName="STM32F407VG" boardId="" boardName=""/>
|
<Device manufacturerId="9" manufacturerName="ST" chipId="344" chipName="STM32F407VG" boardId="" boardName="" boardUrl="" coreId="" coreName=""/>
|
||||||
<BuildOption>
|
<BuildOption>
|
||||||
<Compile>
|
<Compile>
|
||||||
<Option name="OptimizationLevel" value="4"/>
|
<Option name="OptimizationLevel" value="4"/>
|
||||||
@@ -98,8 +100,6 @@
|
|||||||
<Define name="HSE_VALUE=12000000"/>
|
<Define name="HSE_VALUE=12000000"/>
|
||||||
<Define name="STM32F4_PI"/>
|
<Define name="STM32F4_PI"/>
|
||||||
<Define name="ARDUINO_MODE_PINS"/>
|
<Define name="ARDUINO_MODE_PINS"/>
|
||||||
<Define name="SEND_RSSI_DATA"/>
|
|
||||||
<Define name="SERIAL_REPEATER"/>
|
|
||||||
</DefinedSymbols>
|
</DefinedSymbols>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Link useDefault="0">
|
<Link useDefault="0">
|
||||||
@@ -155,8 +155,8 @@
|
|||||||
</DebugOption>
|
</DebugOption>
|
||||||
<ExcludeFile/>
|
<ExcludeFile/>
|
||||||
</Target>
|
</Target>
|
||||||
<Target name="MMDVM_Nucleo_446" isCurrent="0">
|
<Target name="MMDVM_Nucleo_446" isCurrent="1">
|
||||||
<Device manufacturerId="9" manufacturerName="ST" chipId="344" chipName="STM32F407VG" boardId="" boardName=""/>
|
<Device manufacturerId="9" manufacturerName="ST" chipId="261" chipName="STM32F407VG" boardId="" boardName="" boardUrl="" coreId="" coreName=""/>
|
||||||
<BuildOption>
|
<BuildOption>
|
||||||
<Compile>
|
<Compile>
|
||||||
<Option name="OptimizationLevel" value="4"/>
|
<Option name="OptimizationLevel" value="4"/>
|
||||||
@@ -164,6 +164,8 @@
|
|||||||
<Option name="UserEditCompiler" value=""/>
|
<Option name="UserEditCompiler" value=""/>
|
||||||
<Option name="SupportCPlusplus" value="1"/>
|
<Option name="SupportCPlusplus" value="1"/>
|
||||||
<Option name="FPU" value="2"/>
|
<Option name="FPU" value="2"/>
|
||||||
|
<Option name="DEBUG" value="2"/>
|
||||||
|
<Option name="WARNING" value="0"/>
|
||||||
<Includepaths>
|
<Includepaths>
|
||||||
<Includepath path="."/>
|
<Includepath path="."/>
|
||||||
</Includepaths>
|
</Includepaths>
|
||||||
@@ -231,8 +233,8 @@
|
|||||||
</DebugOption>
|
</DebugOption>
|
||||||
<ExcludeFile/>
|
<ExcludeFile/>
|
||||||
</Target>
|
</Target>
|
||||||
<Components path="./">
|
<Components path="./"/>
|
||||||
</Components>
|
<LocalComponents/>
|
||||||
<Files>
|
<Files>
|
||||||
<File name="DMRIdleRX.h" path="DMRIdleRX.h" type="1"/>
|
<File name="DMRIdleRX.h" path="DMRIdleRX.h" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_dac.c" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_dac.c" type="1"/>
|
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_dac.c" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_dac.c" type="1"/>
|
||||||
@@ -242,11 +244,15 @@
|
|||||||
<File name="STM32F4XX_Lib/Device/stm32f4xx.h" path="STM32F4XX_Lib/Device/stm32f4xx.h" type="1"/>
|
<File name="STM32F4XX_Lib/Device/stm32f4xx.h" path="STM32F4XX_Lib/Device/stm32f4xx.h" type="1"/>
|
||||||
<File name="SampleRB.cpp" path="SampleRB.cpp" type="1"/>
|
<File name="SampleRB.cpp" path="SampleRB.cpp" type="1"/>
|
||||||
<File name="CalDStarTX.h" path="CalDStarTX.h" type="1"/>
|
<File name="CalDStarTX.h" path="CalDStarTX.h" type="1"/>
|
||||||
|
<File name="CalNXDN.cpp" path="CalNXDN.cpp" type="1"/>
|
||||||
|
<File name="NXDNTX.cpp" path="NXDNTX.cpp" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/CMSIS/Include/core_cm4.h" path="STM32F4XX_Lib/CMSIS/Include/core_cm4.h" type="1"/>
|
<File name="STM32F4XX_Lib/CMSIS/Include/core_cm4.h" path="STM32F4XX_Lib/CMSIS/Include/core_cm4.h" type="1"/>
|
||||||
|
<File name="I2CTeensy.cpp" path="I2CTeensy.cpp" type="1"/>
|
||||||
<File name="DMRSlotRX.h" path="DMRSlotRX.h" type="1"/>
|
<File name="DMRSlotRX.h" path="DMRSlotRX.h" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_tim.c" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_tim.c" type="1"/>
|
|
||||||
<File name="YSFRX.h" path="YSFRX.h" type="1"/>
|
<File name="YSFRX.h" path="YSFRX.h" type="1"/>
|
||||||
|
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_tim.c" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_tim.c" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/CMSIS/Include" path="" type="2"/>
|
<File name="STM32F4XX_Lib/CMSIS/Include" path="" type="2"/>
|
||||||
|
<File name="NXDNRX.cpp" path="NXDNRX.cpp" type="1"/>
|
||||||
<File name="IO.cpp" path="IO.cpp" type="1"/>
|
<File name="IO.cpp" path="IO.cpp" type="1"/>
|
||||||
<File name="DMRDMORX.cpp" path="DMRDMORX.cpp" type="1"/>
|
<File name="DMRDMORX.cpp" path="DMRDMORX.cpp" type="1"/>
|
||||||
<File name="P25RX.h" path="P25RX.h" type="1"/>
|
<File name="P25RX.h" path="P25RX.h" type="1"/>
|
||||||
@@ -254,28 +260,35 @@
|
|||||||
<File name="STM32F4XX_Lib/CMSIS" path="" type="2"/>
|
<File name="STM32F4XX_Lib/CMSIS" path="" type="2"/>
|
||||||
<File name="SerialArduino.cpp" path="SerialArduino.cpp" type="1"/>
|
<File name="SerialArduino.cpp" path="SerialArduino.cpp" type="1"/>
|
||||||
<File name="SerialPort.cpp" path="SerialPort.cpp" type="1"/>
|
<File name="SerialPort.cpp" path="SerialPort.cpp" type="1"/>
|
||||||
|
<File name="CalP25.cpp" path="CalP25.cpp" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/Device/stm32f4xx_conf.h" path="STM32F4XX_Lib/Device/stm32f4xx_conf.h" type="1"/>
|
<File name="STM32F4XX_Lib/Device/stm32f4xx_conf.h" path="STM32F4XX_Lib/Device/stm32f4xx_conf.h" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_adc.c" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_adc.c" type="1"/>
|
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_adc.c" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_adc.c" type="1"/>
|
||||||
|
<File name="IOSTM_CMSIS.cpp" path="IOSTM_CMSIS.cpp" type="1"/>
|
||||||
<File name="DStarTX.cpp" path="DStarTX.cpp" type="1"/>
|
<File name="DStarTX.cpp" path="DStarTX.cpp" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_usart.c" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_usart.c" type="1"/>
|
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_usart.c" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_usart.c" type="1"/>
|
||||||
<File name="SampleRB.h" path="SampleRB.h" type="1"/>
|
|
||||||
<File name="YSFTX.h" path="YSFTX.h" type="1"/>
|
<File name="YSFTX.h" path="YSFTX.h" type="1"/>
|
||||||
|
<File name="SampleRB.h" path="SampleRB.h" type="1"/>
|
||||||
|
<File name="SerialSTM_CMSIS.cpp" path="SerialSTM_CMSIS.cpp" type="1"/>
|
||||||
<File name="DMRRX.h" path="DMRRX.h" type="1"/>
|
<File name="DMRRX.h" path="DMRRX.h" type="1"/>
|
||||||
<File name="IOTeensy.cpp" path="IOTeensy.cpp" type="1"/>
|
<File name="IOTeensy.cpp" path="IOTeensy.cpp" type="1"/>
|
||||||
<File name="MMDVM.cpp" path="MMDVM.cpp" type="1"/>
|
<File name="MMDVM.cpp" path="MMDVM.cpp" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/CMSIS/Include/core_cmSimd.h" path="STM32F4XX_Lib/CMSIS/Include/core_cmSimd.h" type="1"/>
|
<File name="STM32F4XX_Lib/CMSIS/Include/core_cmSimd.h" path="STM32F4XX_Lib/CMSIS/Include/core_cmSimd.h" type="1"/>
|
||||||
|
<File name="POCSAGTX.cpp" path="POCSAGTX.cpp" type="1"/>
|
||||||
<File name="DMRDMORX.h" path="DMRDMORX.h" type="1"/>
|
<File name="DMRDMORX.h" path="DMRDMORX.h" type="1"/>
|
||||||
|
<File name="GitVersion.h" path="GitVersion.h" type="1"/>
|
||||||
<File name="SerialPort.h" path="SerialPort.h" type="1"/>
|
<File name="SerialPort.h" path="SerialPort.h" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_dac.h" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_dac.h" type="1"/>
|
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_dac.h" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_dac.h" type="1"/>
|
||||||
<File name="CWIdTX.h" path="CWIdTX.h" type="1"/>
|
|
||||||
<File name="STM32F4XX_Lib/Device/system_stm32f4xx.h" path="STM32F4XX_Lib/Device/system_stm32f4xx.h" type="1"/>
|
|
||||||
<File name="STM32F4XX_Lib/CMSIS/Include/core_cmFunc.h" path="STM32F4XX_Lib/CMSIS/Include/core_cmFunc.h" type="1"/>
|
<File name="STM32F4XX_Lib/CMSIS/Include/core_cmFunc.h" path="STM32F4XX_Lib/CMSIS/Include/core_cmFunc.h" type="1"/>
|
||||||
|
<File name="STM32F4XX_Lib/Device/system_stm32f4xx.h" path="STM32F4XX_Lib/Device/system_stm32f4xx.h" type="1"/>
|
||||||
|
<File name="CWIdTX.h" path="CWIdTX.h" type="1"/>
|
||||||
<File name="CalDStarTX.cpp" path="CalDStarTX.cpp" type="1"/>
|
<File name="CalDStarTX.cpp" path="CalDStarTX.cpp" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source" path="" type="2"/>
|
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source" path="" type="2"/>
|
||||||
<File name="CalDMR.h" path="CalDMR.h" type="1"/>
|
<File name="POCSAGTX.h" path="POCSAGTX.h" type="1"/>
|
||||||
<File name="DMRDMOTX.h" path="DMRDMOTX.h" type="1"/>
|
<File name="DMRDMOTX.h" path="DMRDMOTX.h" type="1"/>
|
||||||
|
<File name="CalDMR.h" path="CalDMR.h" type="1"/>
|
||||||
<File name="IODue.cpp" path="IODue.cpp" type="1"/>
|
<File name="IODue.cpp" path="IODue.cpp" type="1"/>
|
||||||
<File name="DMRTX.cpp" path="DMRTX.cpp" type="1"/>
|
<File name="DMRTX.cpp" path="DMRTX.cpp" type="1"/>
|
||||||
|
<File name="CalRSSI.h" path="CalRSSI.h" type="1"/>
|
||||||
<File name="P25RX.cpp" path="P25RX.cpp" type="1"/>
|
<File name="P25RX.cpp" path="P25RX.cpp" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/CMSIS/Lib/GCC" path="" type="2"/>
|
<File name="STM32F4XX_Lib/CMSIS/Lib/GCC" path="" type="2"/>
|
||||||
<File name="STM32F4XX_Lib" path="" type="2"/>
|
<File name="STM32F4XX_Lib" path="" type="2"/>
|
||||||
@@ -286,7 +299,9 @@
|
|||||||
<File name="STM32F4XX_Lib/Device/startup/startup_stm32f4xx.c" path="STM32F4XX_Lib/Device/startup/startup_stm32f4xx.c" type="1"/>
|
<File name="STM32F4XX_Lib/Device/startup/startup_stm32f4xx.c" path="STM32F4XX_Lib/Device/startup/startup_stm32f4xx.c" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/Device/startup" path="" type="2"/>
|
<File name="STM32F4XX_Lib/Device/startup" path="" type="2"/>
|
||||||
<File name="SerialRB.h" path="SerialRB.h" type="1"/>
|
<File name="SerialRB.h" path="SerialRB.h" type="1"/>
|
||||||
|
<File name="NXDNDefines.h" path="NXDNDefines.h" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_gpio.h" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_gpio.h" type="1"/>
|
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_gpio.h" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_gpio.h" type="1"/>
|
||||||
|
<File name="NXDNTX.h" path="NXDNTX.h" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver" path="" type="2"/>
|
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver" path="" type="2"/>
|
||||||
<File name="DMRDefines.h" path="DMRDefines.h" type="1"/>
|
<File name="DMRDefines.h" path="DMRDefines.h" type="1"/>
|
||||||
<File name="CalDMR.cpp" path="CalDMR.cpp" type="1"/>
|
<File name="CalDMR.cpp" path="CalDMR.cpp" type="1"/>
|
||||||
@@ -295,18 +310,22 @@
|
|||||||
<File name="STM32F4XX_Lib/CMSIS/Lib/GCC/libarm_cortexM4lf_math.a" path="STM32F4XX_Lib/CMSIS/Lib/GCC/libarm_cortexM4lf_math.a" type="1"/>
|
<File name="STM32F4XX_Lib/CMSIS/Lib/GCC/libarm_cortexM4lf_math.a" path="STM32F4XX_Lib/CMSIS/Lib/GCC/libarm_cortexM4lf_math.a" type="1"/>
|
||||||
<File name="DStarDefines.h" path="DStarDefines.h" type="1"/>
|
<File name="DStarDefines.h" path="DStarDefines.h" type="1"/>
|
||||||
<File name="DStarRX.h" path="DStarRX.h" type="1"/>
|
<File name="DStarRX.h" path="DStarRX.h" type="1"/>
|
||||||
|
<File name="NXDNRX.h" path="NXDNRX.h" type="1"/>
|
||||||
<File name="Config.h" path="Config.h" type="1"/>
|
<File name="Config.h" path="Config.h" type="1"/>
|
||||||
|
<File name="RingBuff.h" path="RingBuff.h" type="1"/>
|
||||||
<File name="DMRSlotType.cpp" path="DMRSlotType.cpp" type="1"/>
|
<File name="DMRSlotType.cpp" path="DMRSlotType.cpp" type="1"/>
|
||||||
<File name="Globals.h" path="Globals.h" type="1"/>
|
<File name="Globals.h" path="Globals.h" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/Device" path="" type="2"/>
|
<File name="STM32F4XX_Lib/Device" path="" type="2"/>
|
||||||
<File name="CalDStarRX.cpp" path="CalDStarRX.cpp" type="1"/>
|
<File name="CalDStarRX.cpp" path="CalDStarRX.cpp" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_tim.h" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_tim.h" type="1"/>
|
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_tim.h" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_tim.h" type="1"/>
|
||||||
|
<File name="CalNXDN.h" path="CalNXDN.h" type="1"/>
|
||||||
<File name="CalDStarRX.h" path="CalDStarRX.h" type="1"/>
|
<File name="CalDStarRX.h" path="CalDStarRX.h" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include" path="" type="2"/>
|
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include" path="" type="2"/>
|
||||||
|
<File name="CalRSSI.cpp" path="CalRSSI.cpp" type="1"/>
|
||||||
<File name="IO.h" path="IO.h" type="1"/>
|
<File name="IO.h" path="IO.h" type="1"/>
|
||||||
<File name="Utils.cpp" path="Utils.cpp" type="1"/>
|
<File name="Utils.cpp" path="Utils.cpp" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/CMSIS/.DS_Store" path="STM32F4XX_Lib/CMSIS/.DS_Store" type="1"/>
|
|
||||||
<File name="STM32F4XX_Lib/CMSIS/Lib/.DS_Store" path="STM32F4XX_Lib/CMSIS/Lib/.DS_Store" type="1"/>
|
<File name="STM32F4XX_Lib/CMSIS/Lib/.DS_Store" path="STM32F4XX_Lib/CMSIS/Lib/.DS_Store" type="1"/>
|
||||||
|
<File name="STM32F4XX_Lib/CMSIS/.DS_Store" path="STM32F4XX_Lib/CMSIS/.DS_Store" type="1"/>
|
||||||
<File name="Utils.h" path="Utils.h" type="1"/>
|
<File name="Utils.h" path="Utils.h" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/CMSIS/Lib" path="" type="2"/>
|
<File name="STM32F4XX_Lib/CMSIS/Lib" path="" type="2"/>
|
||||||
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/.DS_Store" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/.DS_Store" type="1"/>
|
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/.DS_Store" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/.DS_Store" type="1"/>
|
||||||
@@ -315,6 +334,7 @@
|
|||||||
<File name="YSFDefines.h" path="YSFDefines.h" type="1"/>
|
<File name="YSFDefines.h" path="YSFDefines.h" type="1"/>
|
||||||
<File name="DStarTX.h" path="DStarTX.h" type="1"/>
|
<File name="DStarTX.h" path="DStarTX.h" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_rcc.c" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_rcc.c" type="1"/>
|
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_rcc.c" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_rcc.c" type="1"/>
|
||||||
|
<File name="CalP25.h" path="CalP25.h" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/Device/.DS_Store" path="STM32F4XX_Lib/Device/.DS_Store" type="1"/>
|
<File name="STM32F4XX_Lib/Device/.DS_Store" path="STM32F4XX_Lib/Device/.DS_Store" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_rcc.h" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_rcc.h" type="1"/>
|
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_rcc.h" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_rcc.h" type="1"/>
|
||||||
<File name="P25Defines.h" path="P25Defines.h" type="1"/>
|
<File name="P25Defines.h" path="P25Defines.h" type="1"/>
|
||||||
@@ -324,15 +344,17 @@
|
|||||||
<File name="P25TX.h" path="P25TX.h" type="1"/>
|
<File name="P25TX.h" path="P25TX.h" type="1"/>
|
||||||
<File name="RSSIRB.cpp" path="RSSIRB.cpp" type="1"/>
|
<File name="RSSIRB.cpp" path="RSSIRB.cpp" type="1"/>
|
||||||
<File name="DStarRX.cpp" path="DStarRX.cpp" type="1"/>
|
<File name="DStarRX.cpp" path="DStarRX.cpp" type="1"/>
|
||||||
<File name="DMRSlotRX.cpp" path="DMRSlotRX.cpp" type="1"/>
|
|
||||||
<File name="IOSTM.cpp" path="IOSTM.cpp" type="1"/>
|
<File name="IOSTM.cpp" path="IOSTM.cpp" type="1"/>
|
||||||
|
<File name="DMRSlotRX.cpp" path="DMRSlotRX.cpp" type="1"/>
|
||||||
<File name="P25TX.cpp" path="P25TX.cpp" type="1"/>
|
<File name="P25TX.cpp" path="P25TX.cpp" type="1"/>
|
||||||
<File name="SerialRB.cpp" path="SerialRB.cpp" type="1"/>
|
<File name="SerialRB.cpp" path="SerialRB.cpp" type="1"/>
|
||||||
<File name="CWIdTX.cpp" path="CWIdTX.cpp" type="1"/>
|
<File name="CWIdTX.cpp" path="CWIdTX.cpp" type="1"/>
|
||||||
<File name="DMRIdleRX.cpp" path="DMRIdleRX.cpp" type="1"/>
|
<File name="DMRIdleRX.cpp" path="DMRIdleRX.cpp" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_usart.h" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_usart.h" type="1"/>
|
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_usart.h" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_usart.h" type="1"/>
|
||||||
|
<File name="STM32Utils.h" path="STM32Utils.h" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/.DS_Store" path="STM32F4XX_Lib/.DS_Store" type="1"/>
|
<File name="STM32F4XX_Lib/.DS_Store" path="STM32F4XX_Lib/.DS_Store" type="1"/>
|
||||||
<File name="YSFTX.cpp" path="YSFTX.cpp" type="1"/>
|
<File name="YSFTX.cpp" path="YSFTX.cpp" type="1"/>
|
||||||
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_gpio.c" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_gpio.c" type="1"/>
|
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_gpio.c" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_gpio.c" type="1"/>
|
||||||
</Files>
|
</Files>
|
||||||
|
<Bookmarks/>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (C) 2016 by Andy Uribe CA6JAU
|
# Copyright (C) 2016,2017,2018 by Andy Uribe CA6JAU
|
||||||
# Copyright (C) 2016 by Jim McLaughlin KI6ZUM
|
# Copyright (C) 2016 by Jim McLaughlin KI6ZUM
|
||||||
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
@@ -15,6 +15,54 @@
|
|||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
# MMDVM source files
|
||||||
|
MMDVM_PATH=.
|
||||||
|
|
||||||
|
# STM32 library paths
|
||||||
|
F4_LIB_PATH=./STM32F4XX_Lib
|
||||||
|
F7_LIB_PATH=./STM32F7XX_Lib
|
||||||
|
|
||||||
|
# MCU external clock frequency (Hz)
|
||||||
|
CLK_MMDVM_PI=12000000
|
||||||
|
CLK_NUCLEO=8000000
|
||||||
|
|
||||||
|
# Directory Structure
|
||||||
|
BINDIR=bin
|
||||||
|
OBJDIR_F4=obj_f4
|
||||||
|
OBJDIR_F7=obj_f7
|
||||||
|
|
||||||
|
# Output files
|
||||||
|
BINELF_F4=mmdvm_f4.elf
|
||||||
|
BINHEX_F4=mmdvm_f4.hex
|
||||||
|
BINBIN_F4=mmdvm_f4.bin
|
||||||
|
BINELF_F7=mmdvm_f7.elf
|
||||||
|
BINHEX_F7=mmdvm_f7.hex
|
||||||
|
BINBIN_F7=mmdvm_f7.bin
|
||||||
|
|
||||||
|
# Header directories
|
||||||
|
INC_F4= . $(F4_LIB_PATH)/CMSIS/Include/ $(F4_LIB_PATH)/Device/ $(F4_LIB_PATH)/STM32F4xx_StdPeriph_Driver/include/
|
||||||
|
INCLUDES_F4=$(INC_F4:%=-I%)
|
||||||
|
INC_F7= . $(F7_LIB_PATH)/CMSIS/Include/ $(F7_LIB_PATH)/Device/ $(F7_LIB_PATH)/STM32F7xx_StdPeriph_Driver/inc/
|
||||||
|
INCLUDES_F7=$(INC_F7:%=-I%)
|
||||||
|
|
||||||
|
# CMSIS libraries
|
||||||
|
INCLUDES_LIBS_F4=$(F4_LIB_PATH)/CMSIS/Lib/GCC/libarm_cortexM4lf_math.a
|
||||||
|
INCLUDES_LIBS_F7=$(F7_LIB_PATH)/CMSIS/Lib/GCC/libarm_cortexM7lfsp_math.a
|
||||||
|
|
||||||
|
# STM32F4 Standard Peripheral Libraries source path
|
||||||
|
STD_LIB_F4=$(F4_LIB_PATH)/STM32F4xx_StdPeriph_Driver/source
|
||||||
|
|
||||||
|
# STM32F7 Standard Peripheral Libraries source path
|
||||||
|
STD_LIB_F7=$(F7_LIB_PATH)/STM32F7xx_StdPeriph_Driver/src
|
||||||
|
|
||||||
|
# STM32F4 system source path
|
||||||
|
SYS_DIR_F4=$(F4_LIB_PATH)/Device
|
||||||
|
STARTUP_DIR_F4=$(F4_LIB_PATH)/Device/startup
|
||||||
|
|
||||||
|
# STM32F7 system source path
|
||||||
|
SYS_DIR_F7=$(F7_LIB_PATH)/Device
|
||||||
|
STARTUP_DIR_F7=$(F7_LIB_PATH)/Device/startup
|
||||||
|
|
||||||
# GNU ARM Embedded Toolchain
|
# GNU ARM Embedded Toolchain
|
||||||
CC=arm-none-eabi-gcc
|
CC=arm-none-eabi-gcc
|
||||||
CXX=arm-none-eabi-g++
|
CXX=arm-none-eabi-g++
|
||||||
@@ -27,147 +75,288 @@ NM=arm-none-eabi-nm
|
|||||||
SIZE=arm-none-eabi-size
|
SIZE=arm-none-eabi-size
|
||||||
A2L=arm-none-eabi-addr2line
|
A2L=arm-none-eabi-addr2line
|
||||||
|
|
||||||
# Directory Structure
|
|
||||||
BINDIR=bin
|
|
||||||
|
|
||||||
# Find source files
|
|
||||||
# "SystemRoot" is only defined in Windows
|
# "SystemRoot" is only defined in Windows
|
||||||
ifdef SYSTEMROOT
|
ifdef SYSTEMROOT
|
||||||
ASOURCES=$(shell dir /S /B *.s)
|
CLEANCMD=del /S *.o *.hex *.bin *.elf GitVersion.h
|
||||||
CSOURCES=$(shell dir /S /B *.c)
|
MDDIRS=md $@
|
||||||
CXXSOURCES=$(shell dir /S /B *.cpp)
|
|
||||||
CLEANCMD=del /S *.o *.hex *.bin *.elf
|
|
||||||
MDBIN=md $@
|
|
||||||
else ifdef SystemRoot
|
else ifdef SystemRoot
|
||||||
ASOURCES=$(shell dir /S /B *.s)
|
CLEANCMD=del /S *.o *.hex *.bin *.elf GitVersion.h
|
||||||
CSOURCES=$(shell dir /S /B *.c)
|
MDDIRS=md $@
|
||||||
CXXSOURCES=$(shell dir /S /B *.cpp)
|
|
||||||
CLEANCMD=del /S *.o *.hex *.bin *.elf
|
|
||||||
MDBIN=md $@
|
|
||||||
else
|
else
|
||||||
ASOURCES=$(shell find . -name '*.s')
|
CLEANCMD=rm -f $(OBJ_F4) $(OBJ_F7) $(BINDIR)/*.hex $(BINDIR)/*.bin $(BINDIR)/*.elf GitVersion.h
|
||||||
CSOURCES=$(shell find . -name '*.c')
|
MDDIRS=mkdir $@
|
||||||
CXXSOURCES=$(shell find . -name '*.cpp')
|
|
||||||
CLEANCMD=rm -f $(OBJECTS) $(BINDIR)/$(BINELF) $(BINDIR)/$(BINHEX) $(BINDIR)/$(BINBIN)
|
|
||||||
MDBIN=mkdir $@
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Default reference oscillator frequencies
|
# Default reference oscillator frequencies
|
||||||
ifndef $(OSC)
|
ifndef $(OSC)
|
||||||
ifeq ($(MAKECMDGOALS),pi)
|
ifeq ($(MAKECMDGOALS),pi)
|
||||||
OSC=12000000
|
OSC=$(CLK_MMDVM_PI)
|
||||||
|
else ifeq ($(MAKECMDGOALS),pi-f722)
|
||||||
|
OSC=$(CLK_MMDVM_PI)
|
||||||
else
|
else
|
||||||
OSC=8000000
|
OSC=$(CLK_NUCLEO)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Find header directories
|
# Build object lists
|
||||||
INC= . STM32F4XX_Lib/CMSIS/Include/ STM32F4XX_Lib/Device/ STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/
|
CXXSRC=$(wildcard $(MMDVM_PATH)/*.cpp)
|
||||||
INCLUDES=$(INC:%=-I%)
|
CSRC_STD_F4=$(wildcard $(STD_LIB_F4)/*.c)
|
||||||
|
SYS_F4=$(wildcard $(SYS_DIR_F4)/*.c)
|
||||||
|
STARTUP_F4=$(wildcard $(STARTUP_DIR_F4)/*.c)
|
||||||
|
CSRC_STD_F7=$(wildcard $(STD_LIB_F7)/*.c)
|
||||||
|
SYS_F7=$(wildcard $(SYS_DIR_F7)/*.c)
|
||||||
|
STARTUP_F7=$(wildcard $(STARTUP_DIR_F7)/*.c)
|
||||||
|
OBJ_F4=$(CXXSRC:$(MMDVM_PATH)/%.cpp=$(OBJDIR_F4)/%.o) $(CSRC_STD_F4:$(STD_LIB_F4)/%.c=$(OBJDIR_F4)/%.o) $(SYS_F4:$(SYS_DIR_F4)/%.c=$(OBJDIR_F4)/%.o) $(STARTUP_F4:$(STARTUP_DIR_F4)/%.c=$(OBJDIR_F4)/%.o)
|
||||||
|
OBJ_F7=$(CXXSRC:$(MMDVM_PATH)/%.cpp=$(OBJDIR_F7)/%.o) $(CSRC_STD_F7:$(STD_LIB_F7)/%.c=$(OBJDIR_F7)/%.o) $(SYS_F7:$(SYS_DIR_F7)/%.c=$(OBJDIR_F7)/%.o) $(STARTUP_F7:$(STARTUP_DIR_F7)/%.c=$(OBJDIR_F7)/%.o)
|
||||||
|
|
||||||
# Find libraries
|
# MCU flags
|
||||||
INCLUDES_LIBS=STM32F4XX_Lib/CMSIS/Lib/GCC/libarm_cortexM4lf_math.a
|
MCFLAGS_F4=-mcpu=cortex-m4 -mthumb -mlittle-endian -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb-interwork
|
||||||
LINK_LIBS=
|
MCFLAGS_F7=-mcpu=cortex-m7 -mthumb -mlittle-endian -mfpu=fpv5-sp-d16 -mfloat-abi=hard -mthumb-interwork
|
||||||
|
|
||||||
# Create object list
|
# Compile flags
|
||||||
OBJECTS=$(ASOURCES:%.s=%.o)
|
|
||||||
OBJECTS+=$(CSOURCES:%.c=%.o)
|
|
||||||
OBJECTS+=$(CXXSOURCES:%.cpp=%.o)
|
|
||||||
|
|
||||||
# Define output files ELF & IHEX
|
|
||||||
BINELF=outp.elf
|
|
||||||
BINHEX=outp.hex
|
|
||||||
BINBIN=outp.bin
|
|
||||||
|
|
||||||
# MCU FLAGS
|
|
||||||
MCFLAGS=-mcpu=cortex-m4 -mthumb -mlittle-endian \
|
|
||||||
-mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb-interwork
|
|
||||||
|
|
||||||
# COMPILE FLAGS
|
|
||||||
# STM32F4 Discovery board:
|
# STM32F4 Discovery board:
|
||||||
DEFS_DIS=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F40_41xxx -DSTM32F4_DISCOVERY -DHSE_VALUE=$(OSC)
|
DEFS_DIS=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F40_41xxx -DSTM32F4_DISCOVERY -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
|
||||||
# Pi board:
|
# MMDVM-Pi board:
|
||||||
DEFS_PI=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_PI -DARDUINO_MODE_PINS -DSEND_RSSI_DATA -DSERIAL_REPEATER -DHSE_VALUE=$(OSC)
|
DEFS_PI=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_PI -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
|
||||||
# STM32F4 Nucleo 446 board:
|
# MMDVM-F4M F0DEI board:
|
||||||
DEFS_NUCLEO=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_NUCLEO -DHSE_VALUE=$(OSC)
|
DEFS_F4M=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_F4M -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
|
||||||
|
# STM32F4 Nucleo-64 F446RE board:
|
||||||
|
DEFS_NUCLEO=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_NUCLEO -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
|
||||||
|
# STM32F7 Nucleo-144 F767ZI board:
|
||||||
|
DEFS_NUCLEO_F767=-DUSE_HAL_DRIVER -DSTM32F767xx -DSTM32F7XX -DSTM32F7_NUCLEO -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
|
||||||
|
# MMDVM-Pi F722 board:
|
||||||
|
DEFS_PI_F722=-DUSE_HAL_DRIVER -DSTM32F722xx -DSTM32F7XX -DSTM32F722_PI -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
|
||||||
|
# MMDVM-F7M F0DEI board:
|
||||||
|
DEFS_F7M=-DUSE_HAL_DRIVER -DSTM32F722xx -DSTM32F7XX -DSTM32F722_F7M -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
|
||||||
|
# MMDVM-F7-Hat F0DEI, DB9MAT, DF2ET board:
|
||||||
|
DEFS_F7HAT=-DUSE_HAL_DRIVER -DSTM32F722xx -DSTM32F7XX -DSTM32F722_F7HAT -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
|
||||||
|
# STM32F4 DVM board:
|
||||||
|
DEFS_DVM=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_DVM -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
|
||||||
|
|
||||||
CFLAGS=-c $(MCFLAGS) $(INCLUDES)
|
# Build compiler flags
|
||||||
CXXFLAGS=-c $(MCFLAGS) $(INCLUDES)
|
CFLAGS_F4=-c $(MCFLAGS_F4) $(INCLUDES_F4)
|
||||||
|
CXXFLAGS_F4=-c $(MCFLAGS_F4) $(INCLUDES_F4)
|
||||||
|
CFLAGS_F7=-c $(MCFLAGS_F7) $(INCLUDES_F7)
|
||||||
|
CXXFLAGS_F7=-c $(MCFLAGS_F7) $(INCLUDES_F7)
|
||||||
|
|
||||||
# LINKER FLAGS
|
# Linker flags
|
||||||
LDSCRIPT=stm32f4xx_link.ld
|
LDFLAGS_F4 =-T stm32f4xx_link.ld $(MCFLAGS_F4) --specs=nosys.specs $(INCLUDES_LIBS_F4)
|
||||||
LDFLAGS =-T $(LDSCRIPT) $(MCFLAGS) --specs=nosys.specs $(INCLUDES_LIBS) $(LINK_LIBS)
|
LDFLAGS_F767 =-T stm32f767_link.ld $(MCFLAGS_F7) --specs=nosys.specs $(INCLUDES_LIBS_F7)
|
||||||
|
LDFLAGS_F722 =-T stm32f722_link.ld $(MCFLAGS_F7) --specs=nosys.specs $(INCLUDES_LIBS_F7)
|
||||||
|
|
||||||
|
# Common flags
|
||||||
|
CFLAGS=-Os -ffunction-sections -fdata-sections -fno-builtin -Wno-implicit -DCUSTOM_NEW -DNO_EXCEPTIONS
|
||||||
|
CXXFLAGS=-Os -fno-exceptions -ffunction-sections -fdata-sections -fno-builtin -fno-rtti -DCUSTOM_NEW -DNO_EXCEPTIONS
|
||||||
|
LDFLAGS=-Os --specs=nano.specs
|
||||||
|
|
||||||
# Build Rules
|
# Build Rules
|
||||||
.PHONY: all release dis pi nucleo debug clean
|
.PHONY: all release dis pi pi-f722 f4m nucleo f767 dvm clean
|
||||||
|
|
||||||
# Default target: STM32F4 Discovery board
|
# Default target: Nucleo-64 F446RE board
|
||||||
all: dis
|
all: nucleo
|
||||||
|
|
||||||
pi: CFLAGS+=$(DEFS_PI) -Os -ffunction-sections -fdata-sections -fno-builtin -Wno-implicit -DCUSTOM_NEW -DNO_EXCEPTIONS
|
pi: GitVersion.h
|
||||||
pi: CXXFLAGS+=$(DEFS_PI) -Os -fno-exceptions -ffunction-sections -fdata-sections -fno-builtin -fno-rtti -DCUSTOM_NEW -DNO_EXCEPTIONS
|
pi: CFLAGS+=$(CFLAGS_F4) $(DEFS_PI)
|
||||||
pi: LDFLAGS+=-Os --specs=nano.specs
|
pi: CXXFLAGS+=$(CXXFLAGS_F4) $(DEFS_PI)
|
||||||
pi: release
|
pi: LDFLAGS+=$(LDFLAGS_F4)
|
||||||
|
pi: release_f4
|
||||||
|
|
||||||
nucleo: CFLAGS+=$(DEFS_NUCLEO) -Os -ffunction-sections -fdata-sections -fno-builtin -Wno-implicit -DCUSTOM_NEW -DNO_EXCEPTIONS
|
pi-f722: GitVersion.h
|
||||||
nucleo: CXXFLAGS+=$(DEFS_NUCLEO) -Os -fno-exceptions -ffunction-sections -fdata-sections -fno-builtin -fno-rtti -DCUSTOM_NEW -DNO_EXCEPTIONS
|
pi-f722: CFLAGS+=$(CFLAGS_F7) $(DEFS_PI_F722)
|
||||||
nucleo: LDFLAGS+=-Os --specs=nano.specs
|
pi-f722: CXXFLAGS+=$(CXXFLAGS_F7) $(DEFS_PI_F722)
|
||||||
nucleo: release
|
pi-f722: LDFLAGS+=$(LDFLAGS_F722)
|
||||||
|
pi-f722: release_f7
|
||||||
|
|
||||||
dis: CFLAGS+=$(DEFS_DIS) -Os -ffunction-sections -fdata-sections -fno-builtin -Wno-implicit -DCUSTOM_NEW -DNO_EXCEPTIONS
|
f4m: GitVersion.h
|
||||||
dis: CXXFLAGS+=$(DEFS_DIS) -Os -fno-exceptions -ffunction-sections -fdata-sections -fno-builtin -fno-rtti -DCUSTOM_NEW -DNO_EXCEPTIONS
|
f4m: CFLAGS+=$(CFLAGS_F4) $(DEFS_F4M)
|
||||||
dis: LDFLAGS+=-Os --specs=nano.specs
|
f4m: CXXFLAGS+=$(CXXFLAGS_F4) $(DEFS_F4M)
|
||||||
dis: release
|
f4m: LDFLAGS+=$(LDFLAGS_F4)
|
||||||
|
f4m: release_f4
|
||||||
|
|
||||||
debug: CFLAGS+=-g
|
f7m: GitVersion.h
|
||||||
debug: CXXFLAGS+=-g
|
f7m: CFLAGS+=$(CFLAGS_F7) $(DEFS_F7M)
|
||||||
debug: LDFLAGS+=-g
|
f7m: CXXFLAGS+=$(CXXFLAGS_F7) $(DEFS_F7M)
|
||||||
debug: release
|
f7m: LDFLAGS+=$(LDFLAGS_F722)
|
||||||
|
f7m: release_f7
|
||||||
|
|
||||||
release: $(BINDIR)
|
f7hat: GitVersion.h
|
||||||
release: $(BINDIR)/$(BINHEX)
|
f7hat: CFLAGS+=$(CFLAGS_F7) $(DEFS_F7HAT)
|
||||||
release: $(BINDIR)/$(BINBIN)
|
f7hat: CXXFLAGS+=$(CXXFLAGS_F7) $(DEFS_F7HAT)
|
||||||
|
f7hat: LDFLAGS+=$(LDFLAGS_F722)
|
||||||
|
f7hat: release_f7
|
||||||
|
|
||||||
|
nucleo: GitVersion.h
|
||||||
|
nucleo: CFLAGS+=$(CFLAGS_F4) $(DEFS_NUCLEO)
|
||||||
|
nucleo: CXXFLAGS+=$(CXXFLAGS_F4) $(DEFS_NUCLEO)
|
||||||
|
nucleo: LDFLAGS+=$(LDFLAGS_F4)
|
||||||
|
nucleo: release_f4
|
||||||
|
|
||||||
|
dis: GitVersion.h
|
||||||
|
dis: CFLAGS+=$(CFLAGS_F4) $(DEFS_DIS)
|
||||||
|
dis: CXXFLAGS+=$(CXXFLAGS_F4) $(DEFS_DIS)
|
||||||
|
dis: LDFLAGS+=$(LDFLAGS_F4)
|
||||||
|
dis: release_f4
|
||||||
|
|
||||||
|
f767: GitVersion.h
|
||||||
|
f767: CFLAGS+=$(CFLAGS_F7) $(DEFS_NUCLEO_F767)
|
||||||
|
f767: CXXFLAGS+=$(CXXFLAGS_F7) $(DEFS_NUCLEO_F767)
|
||||||
|
f767: LDFLAGS+=$(LDFLAGS_F767)
|
||||||
|
f767: release_f7
|
||||||
|
|
||||||
|
dvm: GitVersion.h
|
||||||
|
dvm: CFLAGS+=$(CFLAGS_F4) $(DEFS_DVM)
|
||||||
|
dvm: CXXFLAGS+=$(CXXFLAGS_F4) $(DEFS_DVM)
|
||||||
|
dvm: LDFLAGS+=$(LDFLAGS_F4)
|
||||||
|
dvm: release_f4
|
||||||
|
|
||||||
|
release_f4: $(BINDIR)
|
||||||
|
release_f4: $(OBJDIR_F4)
|
||||||
|
release_f4: $(BINDIR)/$(BINHEX_F4)
|
||||||
|
release_f4: $(BINDIR)/$(BINBIN_F4)
|
||||||
|
|
||||||
|
release_f7: $(BINDIR)
|
||||||
|
release_f7: $(OBJDIR_F7)
|
||||||
|
release_f7: $(BINDIR)/$(BINHEX_F7)
|
||||||
|
release_f7: $(BINDIR)/$(BINBIN_F7)
|
||||||
|
|
||||||
$(BINDIR):
|
$(BINDIR):
|
||||||
$(MDBIN)
|
$(MDDIRS)
|
||||||
|
|
||||||
$(BINDIR)/$(BINHEX): $(BINDIR)/$(BINELF)
|
$(OBJDIR_F4):
|
||||||
|
$(MDDIRS)
|
||||||
|
|
||||||
|
$(OBJDIR_F7):
|
||||||
|
$(MDDIRS)
|
||||||
|
|
||||||
|
$(BINDIR)/$(BINHEX_F4): $(BINDIR)/$(BINELF_F4)
|
||||||
$(CP) -O ihex $< $@
|
$(CP) -O ihex $< $@
|
||||||
@echo "Objcopy from ELF to IHEX complete!\n"
|
@echo "Objcopy from ELF to IHEX complete!\n"
|
||||||
|
|
||||||
$(BINDIR)/$(BINBIN): $(BINDIR)/$(BINELF)
|
$(BINDIR)/$(BINBIN_F4): $(BINDIR)/$(BINELF_F4)
|
||||||
$(CP) -O binary $< $@
|
$(CP) -O binary $< $@
|
||||||
@echo "Objcopy from ELF to BINARY complete!\n"
|
@echo "Objcopy from ELF to BINARY complete!\n"
|
||||||
|
|
||||||
$(BINDIR)/$(BINELF): $(OBJECTS)
|
$(BINDIR)/$(BINELF_F4): $(OBJ_F4)
|
||||||
$(CXX) $(OBJECTS) $(LDFLAGS) -o $@
|
$(CXX) $(OBJ_F4) $(LDFLAGS) -o $@
|
||||||
@echo "Linking complete!\n"
|
@echo "Linking complete!\n"
|
||||||
$(SIZE) $(BINDIR)/$(BINELF)
|
$(SIZE) $(BINDIR)/$(BINELF_F4)
|
||||||
|
|
||||||
%.o: %.cpp
|
$(BINDIR)/$(BINHEX_F7): $(BINDIR)/$(BINELF_F7)
|
||||||
|
$(CP) -O ihex $< $@
|
||||||
|
@echo "Objcopy from ELF to IHEX complete!\n"
|
||||||
|
|
||||||
|
$(BINDIR)/$(BINBIN_F7): $(BINDIR)/$(BINELF_F7)
|
||||||
|
$(CP) -O binary $< $@
|
||||||
|
@echo "Objcopy from ELF to BINARY complete!\n"
|
||||||
|
|
||||||
|
$(BINDIR)/$(BINELF_F7): $(OBJ_F7)
|
||||||
|
$(CXX) $(OBJ_F7) $(LDFLAGS) -o $@
|
||||||
|
@echo "Linking complete!\n"
|
||||||
|
$(SIZE) $(BINDIR)/$(BINELF_F7)
|
||||||
|
|
||||||
|
$(OBJDIR_F4)/%.o: $(MMDVM_PATH)/%.cpp
|
||||||
$(CXX) $(CXXFLAGS) $< -o $@
|
$(CXX) $(CXXFLAGS) $< -o $@
|
||||||
@echo "Compiled "$<"!\n"
|
@echo "Compiled "$<"!\n"
|
||||||
|
|
||||||
%.o: %.c
|
$(OBJDIR_F7)/%.o: $(MMDVM_PATH)/%.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) $< -o $@
|
||||||
|
@echo "Compiled "$<"!\n"
|
||||||
|
|
||||||
|
$(OBJDIR_F4)/%.o: $(STD_LIB_F4)/%.c
|
||||||
$(CC) $(CFLAGS) $< -o $@
|
$(CC) $(CFLAGS) $< -o $@
|
||||||
@echo "Compiled "$<"!\n"
|
@echo "Compiled "$<"!\n"
|
||||||
|
|
||||||
%.o: %.s
|
$(OBJDIR_F7)/%.o: $(STD_LIB_F7)/%.c
|
||||||
$(CC) $(CFLAGS) $< -o $@
|
$(CC) $(CFLAGS) $< -o $@
|
||||||
@echo "Assambled "$<"!\n"
|
@echo "Compiled "$<"!\n"
|
||||||
|
|
||||||
|
$(OBJDIR_F4)/%.o: $(SYS_DIR_F4)/%.c
|
||||||
|
$(CC) $(CFLAGS) $< -o $@
|
||||||
|
@echo "Compiled "$<"!\n"
|
||||||
|
|
||||||
|
$(OBJDIR_F4)/%.o: $(STARTUP_DIR_F4)/%.c
|
||||||
|
$(CC) $(CFLAGS) $< -o $@
|
||||||
|
@echo "Compiled "$<"!\n"
|
||||||
|
|
||||||
|
$(OBJDIR_F7)/%.o: $(SYS_DIR_F7)/%.c
|
||||||
|
$(CC) $(CFLAGS) $< -o $@
|
||||||
|
@echo "Compiled "$<"!\n"
|
||||||
|
|
||||||
|
$(OBJDIR_F7)/%.o: $(STARTUP_DIR_F7)/%.c
|
||||||
|
$(CC) $(CFLAGS) $< -o $@
|
||||||
|
@echo "Compiled "$<"!\n"
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(CLEANCMD)
|
$(CLEANCMD)
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
ifneq ($(wildcard /usr/bin/openocd),)
|
ifneq ($(wildcard /usr/bin/openocd),)
|
||||||
/usr/bin/openocd -f /usr/share/openocd/scripts/board/stm32f4discovery.cfg -c "program bin/$(BINELF) verify reset exit"
|
/usr/bin/openocd -f /usr/share/openocd/scripts/interface/stlink-v2-1.cfg -f /usr/share/openocd/scripts/target/stm32f4x.cfg -c "program bin/$(BINELF_F4) verify reset exit"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(wildcard /usr/local/bin/openocd),)
|
ifneq ($(wildcard /usr/local/bin/openocd),)
|
||||||
/usr/local/bin/openocd -f /usr/local/share/openocd/scripts/board/stm32f4discovery.cfg -c "program bin/$(BINELF) verify reset exit"
|
/usr/local/bin/openocd -f /usr/local/share/openocd/scripts/interface/stlink-v2-1.cfg -f /usr/local/share/openocd/scripts/target/stm32f4x.cfg -c "program bin/$(BINELF_F4) verify reset exit"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(wildcard /opt/openocd/bin/openocd),)
|
ifneq ($(wildcard /opt/openocd/bin/openocd),)
|
||||||
/opt/openocd/bin/openocd -f /opt/openocd/share/openocd/scripts/board/stm32f4discovery.cfg -c "program bin/$(BINELF) verify reset exit"
|
/opt/openocd/bin/openocd -f /opt/openocd/share/openocd/scripts/interface/stlink-v2-1.cfg -f /opt/openocd/share/openocd/scripts/target/stm32f4x.cfg -c "program bin/$(BINELF_F4) verify reset exit"
|
||||||
|
endif
|
||||||
|
|
||||||
|
deploy-f7:
|
||||||
|
ifneq ($(wildcard /usr/bin/openocd),)
|
||||||
|
/usr/bin/openocd -f /usr/share/openocd/scripts/interface/stlink-v2-1.cfg -f /usr/share/openocd/scripts/target/stm32f7x.cfg -c "program bin/$(BINELF_F7) verify reset exit"
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(wildcard /usr/local/bin/openocd),)
|
||||||
|
/usr/local/bin/openocd -f /usr/local/share/openocd/scripts/interface/stlink-v2-1.cfg -f /usr/local/share/openocd/scripts/target/stm32f7x.cfg -c "program bin/$(BINELF_F7) verify reset exit"
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(wildcard /opt/openocd/bin/openocd),)
|
||||||
|
/opt/openocd/bin/openocd -f /opt/openocd/share/openocd/scripts/interface/stlink-v2-1.cfg -f /opt/openocd/share/openocd/scripts/target/stm32f7x.cfg -c "program bin/$(BINELF_F7) verify reset exit"
|
||||||
|
endif
|
||||||
|
|
||||||
|
deploy-pi:
|
||||||
|
ifneq ($(wildcard /usr/local/bin/stm32flash),)
|
||||||
|
-/usr/local/bin/stm32flash -i 20,-21,21:-20,21 /dev/ttyAMA0
|
||||||
|
-/usr/local/bin/stm32ld /dev/ttyAMA0 57600 bin/$(BINBIN_F4)
|
||||||
|
/usr/local/bin/stm32flash -v -w bin/$(BINBIN_F4) -g 0x0 -R -c /dev/ttyAMA0
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(wildcard /usr/bin/stm32flash),)
|
||||||
|
-/usr/bin/stm32flash -i 20,-21,21:-20,21 /dev/ttyAMA0
|
||||||
|
-/usr/bin/stm32ld /dev/ttyAMA0 57600 bin/$(BINBIN_F4)
|
||||||
|
/usr/bin/stm32flash -v -w bin/$(BINBIN_F4) -g 0x0 -R -c /dev/ttyAMA0
|
||||||
|
endif
|
||||||
|
|
||||||
|
deploy-f4m: deploy-pi
|
||||||
|
deploy-dvm: deploy-pi
|
||||||
|
|
||||||
|
deploy-pi-f7:
|
||||||
|
ifneq ($(wildcard /usr/local/bin/stm32flash),)
|
||||||
|
-/usr/local/bin/stm32flash -i 20,-21,21:-20,21 /dev/ttyAMA0
|
||||||
|
-/usr/local/bin/stm32ld /dev/ttyAMA0 57600 bin/$(BINBIN_F7)
|
||||||
|
/usr/local/bin/stm32flash -v -w bin/$(BINBIN_F7) -g 0x0 -R -c /dev/ttyAMA0
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(wildcard /usr/bin/stm32flash),)
|
||||||
|
-/usr/bin/stm32flash -i 20,-21,21:-20,21 /dev/ttyAMA0
|
||||||
|
-/usr/bin/stm32ld /dev/ttyAMA0 57600 bin/$(BINBIN_F7)
|
||||||
|
/usr/bin/stm32flash -v -w bin/$(BINBIN_F7) -g 0x0 -R -c /dev/ttyAMA0
|
||||||
|
endif
|
||||||
|
|
||||||
|
deploy-f7m: deploy-pi-f7
|
||||||
|
deploy-f7hat: deploy-pi-f7
|
||||||
|
|
||||||
|
# Export the current git version if the index file exists, else 000...
|
||||||
|
GitVersion.h:
|
||||||
|
ifdef SYSTEMROOT
|
||||||
|
echo #define GITVERSION "0000000" > $@
|
||||||
|
else ifdef SystemRoot
|
||||||
|
echo #define GITVERSION "0000000" > $@
|
||||||
|
else
|
||||||
|
ifneq ("$(wildcard .git/index)","")
|
||||||
|
echo "#define GITVERSION \"$(shell git rev-parse --short HEAD)\"" > $@
|
||||||
|
else
|
||||||
|
echo "#define GITVERSION \"0000000\"" > $@
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -0,0 +1,189 @@
|
|||||||
|
#!/usr/bin/make
|
||||||
|
# makefile for the arduino due (works with arduino IDE 1.6.11)
|
||||||
|
#
|
||||||
|
# The original file can be found at https://github.com/pauldreik/arduino-due-makefile
|
||||||
|
#
|
||||||
|
# USAGE: put this file in the same dir as your .ino file is.
|
||||||
|
# configure the PORT variable and ADIR at the top of the file
|
||||||
|
# to match your local configuration.
|
||||||
|
# Type make upload to compile and upload.
|
||||||
|
#
|
||||||
|
|
||||||
|
#user specific settings:
|
||||||
|
#where to find the IDE
|
||||||
|
ADIR:=$(HOME)/.arduino15
|
||||||
|
#which serial port to use (add a file with SUBSYSTEMS=="usb",
|
||||||
|
#ATTRS{product}=="Arduino Due Prog. Port", ATTRS{idProduct}=="003d",
|
||||||
|
#ATTRS{idVendor}=="2341", SYMLINK+="arduino_due" in /etc/udev/rules.d/
|
||||||
|
#to get this working). Do not prefix the port with /dev/, just take
|
||||||
|
#the basename.
|
||||||
|
PORT:=ttyACM0
|
||||||
|
#if you want to verify the bossac upload, define this to -v
|
||||||
|
VERIFY:=-v
|
||||||
|
|
||||||
|
|
||||||
|
#end of user configuration.
|
||||||
|
|
||||||
|
|
||||||
|
#then some general settings. They should not be necessary to modify.
|
||||||
|
#CXX:=$(ADIR)/tools/g++_arm_none_eabi/bin/arm-none-eabi-g++
|
||||||
|
CXX:=$(ADIR)/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi-g++
|
||||||
|
#CC:=$(ADIR)/tools/g++_arm_none_eabi/bin/arm-none-eabi-gcc
|
||||||
|
CC:=$(ADIR)/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi-gcc
|
||||||
|
OBJCOPY:=$(ADIR)/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi-objcopy
|
||||||
|
|
||||||
|
C:=$(CC)
|
||||||
|
#SAM:=arduino/sam/
|
||||||
|
SAM:=$(ADIR)/packages/arduino/hardware/sam/1.6.11
|
||||||
|
#CMSIS:=arduino/sam/system/CMSIS/
|
||||||
|
#LIBSAM:=arduino/sam/system/libsam
|
||||||
|
TMPDIR:=$(PWD)/build
|
||||||
|
AR:=$(ADIR)/tools/g++_arm_none_eabi/bin/arm-none-eabi-ar
|
||||||
|
AR:=$(ADIR)/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi-ar
|
||||||
|
|
||||||
|
|
||||||
|
#all these values are hard coded and should maybe be configured somehow else,
|
||||||
|
#like olikraus does in his makefile.
|
||||||
|
DEFINES:=-Dprintf=iprintf -DF_CPU=84000000 -DARDUINO=10611 -D__SAM3X8E__ -DUSB_PID=0x003e -DUSB_VID=0x2341 -DUSBCON \
|
||||||
|
-DARDUINO_SAM_DUE -DARDUINO_ARCH_SAM '-DUSB_MANUFACTURER="Arduino LLC"' '-DUSB_PRODUCT="Arduino Due"' \
|
||||||
|
-DMADEBYMAKEFILE
|
||||||
|
|
||||||
|
INCLUDES:=-I$(SAM)/system/libsam -I$(SAM)/system/CMSIS/CMSIS/Include/ \
|
||||||
|
-I$(SAM)/system/CMSIS/Device/ATMEL/ -I$(SAM)/cores/arduino \
|
||||||
|
-I$(SAM)/variants/arduino_due_x
|
||||||
|
|
||||||
|
#also include the current dir for convenience
|
||||||
|
INCLUDES += -I.
|
||||||
|
|
||||||
|
#compilation flags common to both c and c++
|
||||||
|
COMMON_FLAGS:=-g -Os -w -ffunction-sections -fdata-sections -nostdlib \
|
||||||
|
--param max-inline-insns-single=500 -mcpu=cortex-m3 -mthumb \
|
||||||
|
-fno-threadsafe-statics
|
||||||
|
#for compiling c (do not warn, this is not our code)
|
||||||
|
CFLAGS:=$(COMMON_FLAGS) -std=gnu11
|
||||||
|
#for compiling c++
|
||||||
|
CXXFLAGS:=$(COMMON_FLAGS) -fno-rtti -fno-exceptions -std=gnu++11 -Wall -Wextra
|
||||||
|
|
||||||
|
#let the results be named after the project
|
||||||
|
PROJNAME:=$(shell basename *.ino .ino)
|
||||||
|
|
||||||
|
#we will make a new mainfile from the ino file.
|
||||||
|
NEWMAINFILE:=$(TMPDIR)/$(PROJNAME).ino.cpp
|
||||||
|
|
||||||
|
#our own sourcefiles is the (converted) ino file and any local cpp files
|
||||||
|
MYSRCFILES:=$(NEWMAINFILE) $(shell ls *.cpp 2>/dev/null)
|
||||||
|
MYOBJFILES:=$(addsuffix .o,$(addprefix $(TMPDIR)/,$(notdir $(MYSRCFILES))))
|
||||||
|
|
||||||
|
#These source files are the ones forming core.a
|
||||||
|
CORESRCXX:=$(shell ls ${SAM}/cores/arduino/*.cpp ${SAM}/cores/arduino/USB/*.cpp ${SAM}/variants/arduino_due_x/variant.cpp)
|
||||||
|
CORESRC:=$(shell ls ${SAM}/cores/arduino/*.c)
|
||||||
|
|
||||||
|
#hey this one is needed too: $(SAM)/cores/arduino/wiring_pulse_asm.S" add -x assembler-with-cpp
|
||||||
|
#and this one: /1.6.11/cores/arduino/avr/dtostrf.c but it seems to work
|
||||||
|
#anyway, probably because I do not use that functionality.
|
||||||
|
|
||||||
|
#convert the core source files to object files. assume no clashes.
|
||||||
|
COREOBJSXX:=$(addprefix $(TMPDIR)/core/,$(notdir $(CORESRCXX)) )
|
||||||
|
COREOBJSXX:=$(addsuffix .o,$(COREOBJSXX))
|
||||||
|
COREOBJS:=$(addprefix $(TMPDIR)/core/,$(notdir $(CORESRC)) )
|
||||||
|
COREOBJS:=$(addsuffix .o,$(COREOBJS))
|
||||||
|
|
||||||
|
default:
|
||||||
|
@echo default rule, does nothing. Try make compile or make upload.
|
||||||
|
|
||||||
|
#This rule is good to just make sure stuff compiles, without having to wait
|
||||||
|
#for bossac.
|
||||||
|
compile: GitVersion.h $(TMPDIR)/$(PROJNAME).elf $(TMPDIR)/$(PROJNAME).bin
|
||||||
|
|
||||||
|
#This is a make rule template to create object files from the source files.
|
||||||
|
# arg 1=src file
|
||||||
|
# arg 2=object file
|
||||||
|
# arg 3= XX if c++, empty if c
|
||||||
|
define OBJ_template
|
||||||
|
$(2): $(1)
|
||||||
|
$(C$(3)) -MD -c $(C$(3)FLAGS) $(DEFINES) $(INCLUDES) $(1) -o $(2)
|
||||||
|
endef
|
||||||
|
#now invoke the template both for c++ sources
|
||||||
|
$(foreach src,$(CORESRCXX), $(eval $(call OBJ_template,$(src),$(addsuffix .o,$(addprefix $(TMPDIR)/core/,$(notdir $(src)))),XX) ) )
|
||||||
|
#...and for c sources:
|
||||||
|
$(foreach src,$(CORESRC), $(eval $(call OBJ_template,$(src),$(addsuffix .o,$(addprefix $(TMPDIR)/core/,$(notdir $(src)))),) ) )
|
||||||
|
|
||||||
|
#and our own c++ sources
|
||||||
|
$(foreach src,$(MYSRCFILES), $(eval $(call OBJ_template,$(src),$(addsuffix .o,$(addprefix $(TMPDIR)/,$(notdir $(src)))),XX) ) )
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
test ! -d $(TMPDIR) || rm -rf $(TMPDIR)
|
||||||
|
$(RM) GitVersion.h
|
||||||
|
|
||||||
|
.PHONY: .FORCE upload default
|
||||||
|
|
||||||
|
$(TMPDIR):
|
||||||
|
mkdir -p $(TMPDIR)
|
||||||
|
|
||||||
|
$(TMPDIR)/core:
|
||||||
|
mkdir -p $(TMPDIR)/core
|
||||||
|
|
||||||
|
#creates the cpp file from the .ino file
|
||||||
|
$(NEWMAINFILE): $(PROJNAME).ino
|
||||||
|
cat $(SAM)/cores/arduino/main.cpp > $(NEWMAINFILE)
|
||||||
|
cat $(PROJNAME).ino >> $(NEWMAINFILE)
|
||||||
|
echo 'extern "C" void __cxa_pure_virtual() {while (true);}' >> $(NEWMAINFILE)
|
||||||
|
|
||||||
|
#include the dependencies for our own files
|
||||||
|
-include $(MYOBJFILES:.o=.d)
|
||||||
|
|
||||||
|
#create the core library from the core objects. Do this EXACTLY as the
|
||||||
|
#arduino IDE does it, seems *really* picky about this.
|
||||||
|
#Sorry for the hard coding.
|
||||||
|
$(TMPDIR)/core.a: $(TMPDIR)/core $(COREOBJS) $(COREOBJSXX)
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/wiring_shift.c.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/wiring_analog.c.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/itoa.c.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/cortex_handlers.c.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/hooks.c.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/wiring.c.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/WInterrupts.c.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/syscalls_sam3.c.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/iar_calls_sam3.c.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/wiring_digital.c.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/Print.cpp.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/USARTClass.cpp.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/WString.cpp.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/PluggableUSB.cpp.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/USBCore.cpp.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/CDC.cpp.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/wiring_pulse.cpp.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/UARTClass.cpp.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/main.cpp.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/new.cpp.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/watchdog.cpp.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/Stream.cpp.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/RingBuffer.cpp.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/IPAddress.cpp.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/Reset.cpp.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/WMath.cpp.o
|
||||||
|
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/variant.cpp.o
|
||||||
|
|
||||||
|
#link our own object files with core to form the elf file
|
||||||
|
$(TMPDIR)/$(PROJNAME).elf: $(TMPDIR)/core.a $(TMPDIR)/core/syscalls_sam3.c.o $(MYOBJFILES)
|
||||||
|
$(CC) -mcpu=cortex-m3 -mthumb -Os -Wl,--gc-sections -T$(SAM)/variants/arduino_due_x/linker_scripts/gcc/flash.ld -Wl,-Map,$(NEWMAINFILE).map -o $@ -L$(TMPDIR) -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--start-group -u _sbrk -u link -u _close -u _fstat -u _isatty -u _lseek -u _read -u _write -u _exit -u kill -u _getpid $(MYOBJFILES) $(TMPDIR)/core/variant.cpp.o $(SAM)/variants/arduino_due_x/libsam_sam3x8e_gcc_rel.a $(SAM)/system/CMSIS/CMSIS/Lib/GCC/libarm_cortexM3l_math.a $(TMPDIR)/core.a -Wl,--end-group -lm -gcc
|
||||||
|
|
||||||
|
#copy from the hex to our bin file (why?)
|
||||||
|
$(TMPDIR)/$(PROJNAME).bin: $(TMPDIR)/$(PROJNAME).elf
|
||||||
|
$(OBJCOPY) -O binary $< $@
|
||||||
|
|
||||||
|
#upload to the arduino by first resetting it (stty) and the running bossac
|
||||||
|
upload: compile
|
||||||
|
stty -F /dev/$(PORT) cs8 1200 hupcl
|
||||||
|
$(ADIR)/packages/arduino/tools/bossac/1.6.1-arduino/bossac -i --port=$(PORT) -U false -e -w $(VERIFY) -b $(TMPDIR)/$(PROJNAME).bin -R
|
||||||
|
|
||||||
|
# Export the current git version if the index file exists, else 000...
|
||||||
|
GitVersion.h: .FORCE
|
||||||
|
ifneq ("$(wildcard .git/index)","")
|
||||||
|
echo "#define GITVERSION \"$(shell git rev-parse --short HEAD)\"" > $@
|
||||||
|
else
|
||||||
|
echo "#define GITVERSION \"0000000\"" > $@
|
||||||
|
endif
|
||||||
|
|
||||||
|
.FORCE:
|
||||||
+151
@@ -0,0 +1,151 @@
|
|||||||
|
# The name for the project
|
||||||
|
TARGET:=mmdvm
|
||||||
|
|
||||||
|
# The CPU architecture (will be used for -mcpu)
|
||||||
|
MCPU:=cortex-m3
|
||||||
|
MCU:=STM32F105xC
|
||||||
|
|
||||||
|
# The source files of the project
|
||||||
|
CSRC:=
|
||||||
|
CXXSRC:=$(wildcard *.cpp)
|
||||||
|
|
||||||
|
# Include directory for the system include files and system source file
|
||||||
|
SYSDIR:=system_stm32f1xx
|
||||||
|
SYSSRC:=$(SYSDIR)/system_stm32f1xx.c
|
||||||
|
|
||||||
|
# Other include directories
|
||||||
|
INCDIR:=
|
||||||
|
|
||||||
|
# Definitions
|
||||||
|
CDEFS:=
|
||||||
|
CXXDEFS:=
|
||||||
|
|
||||||
|
# The name of the startup file which matches to the architecture (MCPU)
|
||||||
|
STARTUP:=$(SYSDIR)/startup_stm32f105xc.S
|
||||||
|
STARTUP_DEFS=
|
||||||
|
|
||||||
|
# Include directory for CMSIS
|
||||||
|
CMSISDIR:=/opt/STM32Cube_FW_F1_V1.4.0/Drivers/CMSIS
|
||||||
|
|
||||||
|
# Libraries
|
||||||
|
LIBDIR:=
|
||||||
|
LIBS:=-larm_cortexM3l_math
|
||||||
|
|
||||||
|
# Name of the linker script
|
||||||
|
LDSCRIPT:=$(SYSDIR)/gcc.ld
|
||||||
|
|
||||||
|
# Target objects and binaries directory
|
||||||
|
OBJDIR:=obj
|
||||||
|
BINDIR:=bin
|
||||||
|
|
||||||
|
# Port definition for programming via bootloader (using stm32flash)
|
||||||
|
BL_PORT:=ttyUSB0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Internal Variables
|
||||||
|
ELF:=$(BINDIR)/$(TARGET).elf
|
||||||
|
HEX:=$(BINDIR)/$(TARGET).hex
|
||||||
|
DIS:=$(BINDIR)/$(TARGET).dis
|
||||||
|
MAP:=$(BINDIR)/$(TARGET).map
|
||||||
|
OBJ:=$(CSRC:%.c=$(OBJDIR)/%.o) $(CXXSRC:%.cpp=$(OBJDIR)/%.o)
|
||||||
|
OBJ+=$(SYSSRC:$(SYSDIR)/%.c=$(OBJDIR)/%.o) $(STARTUP:$(SYSDIR)/%.S=$(OBJDIR)/%.o)
|
||||||
|
|
||||||
|
# Replace standard build tools by arm tools
|
||||||
|
CC:=arm-none-eabi-gcc
|
||||||
|
CXX:=arm-none-eabi-g++
|
||||||
|
AS:=arm-none-eabi-gcc
|
||||||
|
LD:=arm-none-eabi-g++
|
||||||
|
OBJCOPY:=arm-none-eabi-objcopy
|
||||||
|
OBJDUMP:=arm-none-eabi-objdump
|
||||||
|
SIZE:=arm-none-eabi-size
|
||||||
|
|
||||||
|
# Common flags
|
||||||
|
COMMON_FLAGS =-mthumb -mlittle-endian -mcpu=$(MCPU)
|
||||||
|
COMMON_FLAGS+= -Wall
|
||||||
|
COMMON_FLAGS+= -I. -I$(CMSISDIR)/Include -I$(CMSISDIR)/Device/ST/STM32F1xx/Include -I$(SYSDIR)
|
||||||
|
COMMON_FLAGS+= $(addprefix -I,$(INCDIR))
|
||||||
|
COMMON_FLAGS+= -D$(MCU)
|
||||||
|
COMMON_FLAGS+= -Os -flto -ffunction-sections -fdata-sections
|
||||||
|
COMMON_FLAGS+= -g
|
||||||
|
# Assembler flags
|
||||||
|
ASFLAGS:=$(COMMON_FLAGS)
|
||||||
|
# C flags
|
||||||
|
CFLAGS:=$(COMMON_FLAGS) $(addprefix -D,$(CDEFS))
|
||||||
|
CFLAGS+= -std=gnu11 -nostdlib
|
||||||
|
# CXX flags
|
||||||
|
CXXFLAGS:=$(COMMON_FLAGS) $(addprefix -D,$(CXXDEFS))
|
||||||
|
CXXFLAGS+= -nostdlib -fno-exceptions -fno-rtti
|
||||||
|
# LD flags
|
||||||
|
LDFLAGS:=$(COMMON_FLAGS) -Wl,--gc-sections -Wl,-Map=$(MAP) -Wl,--no-wchar-size-warning
|
||||||
|
LDFLAGS+= --specs=nosys.specs --specs=nano.specs
|
||||||
|
LDFLAGS+= -L$(CMSISDIR)/Lib/GCC/ $(addprefix -L,$(LIBDIR))
|
||||||
|
LDLIBS:=-T$(LDSCRIPT) $(LIBS)
|
||||||
|
|
||||||
|
# Dependecies
|
||||||
|
DEPENDS:=$(CSRC:%.c=$(OBJDIR)/%.d) $(CXXSRC:%.cpp=$(OBJDIR)/%.d)
|
||||||
|
|
||||||
|
|
||||||
|
# Additional Suffixes
|
||||||
|
.SUFFIXES: .elf .hex
|
||||||
|
|
||||||
|
# Targets
|
||||||
|
.PHONY: all
|
||||||
|
all: $(DIS) $(HEX)
|
||||||
|
$(SIZE) $(ELF)
|
||||||
|
|
||||||
|
.PHONY: program
|
||||||
|
program: $(HEX) $(ELF)
|
||||||
|
openocd -f openocd.cfg \
|
||||||
|
-c "program $(HEX) verify reset exit"
|
||||||
|
$(SIZE) $(ELF)
|
||||||
|
|
||||||
|
.PHONY: program_bl
|
||||||
|
program_bl: $(HEX) $(ELF)
|
||||||
|
stm32flash -w $(HEX) -v /dev/$(BL_PORT)
|
||||||
|
$(SIZE) $(ELF)
|
||||||
|
|
||||||
|
.PHONY: run
|
||||||
|
run: $(HEX) $(ELF)
|
||||||
|
openocd -f openocd.cfg \
|
||||||
|
-c "init" -c "reset" -c "exit"
|
||||||
|
|
||||||
|
.PHONY: debug
|
||||||
|
debug: $(ELF)
|
||||||
|
./debug.sh $(ELF)
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
$(RM) $(OBJ) $(HEX) $(ELF) $(DIS) $(MAP) $(DEPENDS)
|
||||||
|
|
||||||
|
# implicit rules
|
||||||
|
.elf.hex:
|
||||||
|
$(OBJCOPY) -O ihex $< $@
|
||||||
|
|
||||||
|
$(OBJDIR)/%.o: %.c
|
||||||
|
$(CC) -MMD $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(OBJDIR)/%.o: %.cpp
|
||||||
|
$(CXX) -MMD $(CXXFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(OBJDIR)/%.o: $(SYSDIR)/%.c
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(OBJDIR)/%.o: $(SYSDIR)/%.S
|
||||||
|
$(AS) $(ASFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
# explicit rules
|
||||||
|
$(OBJDIR):
|
||||||
|
mkdir -p $(OBJDIR)
|
||||||
|
|
||||||
|
$(BINDIR):
|
||||||
|
mkdir -p $(BINDIR)
|
||||||
|
|
||||||
|
$(ELF): $(OBJDIR) $(BINDIR) $(OBJ)
|
||||||
|
$(LD) $(OBJ) $(LDFLAGS) $(LDLIBS) -o $@
|
||||||
|
|
||||||
|
$(DIS): $(ELF)
|
||||||
|
$(OBJDUMP) -S $< > $@
|
||||||
|
|
||||||
|
# include dependecies
|
||||||
|
-include $(DEPENDS)
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016,2017,2018 by Jonathan Naylor G4KLX
|
||||||
|
*
|
||||||
|
* 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(NXDNDEFINES_H)
|
||||||
|
#define NXDNDEFINES_H
|
||||||
|
|
||||||
|
const unsigned int NXDN_RADIO_SYMBOL_LENGTH = 20U; // At 48 kHz sample rate
|
||||||
|
|
||||||
|
const unsigned int NXDN_FRAME_LENGTH_BITS = 384U;
|
||||||
|
const unsigned int NXDN_FRAME_LENGTH_BYTES = NXDN_FRAME_LENGTH_BITS / 8U;
|
||||||
|
const unsigned int NXDN_FRAME_LENGTH_SYMBOLS = NXDN_FRAME_LENGTH_BITS / 2U;
|
||||||
|
const unsigned int NXDN_FRAME_LENGTH_SAMPLES = NXDN_FRAME_LENGTH_SYMBOLS * NXDN_RADIO_SYMBOL_LENGTH;
|
||||||
|
|
||||||
|
const unsigned int NXDN_FSW_LENGTH_BITS = 20U;
|
||||||
|
const unsigned int NXDN_FSW_LENGTH_SYMBOLS = NXDN_FSW_LENGTH_BITS / 2U;
|
||||||
|
const unsigned int NXDN_FSW_LENGTH_SAMPLES = NXDN_FSW_LENGTH_SYMBOLS * NXDN_RADIO_SYMBOL_LENGTH;
|
||||||
|
|
||||||
|
const uint8_t NXDN_FSW_BYTES[] = {0xCDU, 0xF5U, 0x90U};
|
||||||
|
const uint8_t NXDN_FSW_BYTES_MASK[] = {0xFFU, 0xFFU, 0xF0U};
|
||||||
|
const uint8_t NXDN_FSW_BYTES_LENGTH = 3U;
|
||||||
|
|
||||||
|
const uint32_t NXDN_FSW_BITS = 0x000CDF59U;
|
||||||
|
const uint32_t NXDN_FSW_BITS_MASK = 0x000FFFFFU;
|
||||||
|
|
||||||
|
// C D F 5 9
|
||||||
|
// 11 00 11 01 11 11 01 01 10 01
|
||||||
|
// -3 +1 -3 +3 -3 -3 +3 +3 -1 +3
|
||||||
|
|
||||||
|
const int8_t NXDN_FSW_SYMBOLS_VALUES[] = {-3, +1, -3, +3, -3, -3, +3, +3, -1, +3};
|
||||||
|
|
||||||
|
const uint16_t NXDN_FSW_SYMBOLS = 0x014DU;
|
||||||
|
const uint16_t NXDN_FSW_SYMBOLS_MASK = 0x03FFU;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
+405
@@ -0,0 +1,405 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2009-2018 by Jonathan Naylor G4KLX
|
||||||
|
*
|
||||||
|
* 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
#include "Globals.h"
|
||||||
|
#include "NXDNRX.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
const q15_t SCALING_FACTOR = 18750; // Q15(0.55)
|
||||||
|
|
||||||
|
const uint8_t MAX_FSW_BIT_START_ERRS = 1U;
|
||||||
|
const uint8_t MAX_FSW_BIT_RUN_ERRS = 3U;
|
||||||
|
|
||||||
|
const uint8_t MAX_FSW_SYMBOLS_ERRS = 2U;
|
||||||
|
|
||||||
|
const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
||||||
|
|
||||||
|
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
||||||
|
|
||||||
|
const uint8_t NOAVEPTR = 99U;
|
||||||
|
|
||||||
|
const uint16_t NOENDPTR = 9999U;
|
||||||
|
|
||||||
|
const unsigned int MAX_FSW_FRAMES = 5U + 1U;
|
||||||
|
|
||||||
|
CNXDNRX::CNXDNRX() :
|
||||||
|
m_state(NXDNRXS_NONE),
|
||||||
|
m_bitBuffer(),
|
||||||
|
m_buffer(),
|
||||||
|
m_bitPtr(0U),
|
||||||
|
m_dataPtr(0U),
|
||||||
|
m_startPtr(NOENDPTR),
|
||||||
|
m_endPtr(NOENDPTR),
|
||||||
|
m_fswPtr(NOENDPTR),
|
||||||
|
m_minFSWPtr(NOENDPTR),
|
||||||
|
m_maxFSWPtr(NOENDPTR),
|
||||||
|
m_maxCorr(0),
|
||||||
|
m_lostCount(0U),
|
||||||
|
m_countdown(0U),
|
||||||
|
m_centre(),
|
||||||
|
m_centreVal(0),
|
||||||
|
m_threshold(),
|
||||||
|
m_thresholdVal(0),
|
||||||
|
m_averagePtr(NOAVEPTR),
|
||||||
|
m_rssiAccum(0U),
|
||||||
|
m_rssiCount(0U)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNXDNRX::reset()
|
||||||
|
{
|
||||||
|
m_state = NXDNRXS_NONE;
|
||||||
|
m_dataPtr = 0U;
|
||||||
|
m_bitPtr = 0U;
|
||||||
|
m_maxCorr = 0;
|
||||||
|
m_averagePtr = NOAVEPTR;
|
||||||
|
m_startPtr = NOENDPTR;
|
||||||
|
m_endPtr = NOENDPTR;
|
||||||
|
m_fswPtr = NOENDPTR;
|
||||||
|
m_minFSWPtr = NOENDPTR;
|
||||||
|
m_maxFSWPtr = NOENDPTR;
|
||||||
|
m_centreVal = 0;
|
||||||
|
m_thresholdVal = 0;
|
||||||
|
m_lostCount = 0U;
|
||||||
|
m_countdown = 0U;
|
||||||
|
m_rssiAccum = 0U;
|
||||||
|
m_rssiCount = 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNXDNRX::samples(const q15_t* samples, uint16_t* rssi, uint8_t length)
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0U; i < length; i++) {
|
||||||
|
q15_t sample = samples[i];
|
||||||
|
|
||||||
|
m_rssiAccum += rssi[i];
|
||||||
|
m_rssiCount++;
|
||||||
|
|
||||||
|
m_bitBuffer[m_bitPtr] <<= 1;
|
||||||
|
if (sample < 0)
|
||||||
|
m_bitBuffer[m_bitPtr] |= 0x01U;
|
||||||
|
|
||||||
|
m_buffer[m_dataPtr] = sample;
|
||||||
|
|
||||||
|
switch (m_state) {
|
||||||
|
case NXDNRXS_DATA:
|
||||||
|
processData(sample);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
processNone(sample);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_dataPtr++;
|
||||||
|
if (m_dataPtr >= NXDN_FRAME_LENGTH_SAMPLES)
|
||||||
|
m_dataPtr = 0U;
|
||||||
|
|
||||||
|
m_bitPtr++;
|
||||||
|
if (m_bitPtr >= NXDN_RADIO_SYMBOL_LENGTH)
|
||||||
|
m_bitPtr = 0U;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNXDNRX::processNone(q15_t sample)
|
||||||
|
{
|
||||||
|
bool ret = correlateFSW();
|
||||||
|
if (ret) {
|
||||||
|
// On the first sync, start the countdown to the state change
|
||||||
|
if (m_countdown == 0U) {
|
||||||
|
m_rssiAccum = 0U;
|
||||||
|
m_rssiCount = 0U;
|
||||||
|
|
||||||
|
io.setDecode(true);
|
||||||
|
io.setADCDetection(true);
|
||||||
|
|
||||||
|
m_averagePtr = NOAVEPTR;
|
||||||
|
|
||||||
|
m_countdown = 5U;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_countdown > 0U)
|
||||||
|
m_countdown--;
|
||||||
|
|
||||||
|
if (m_countdown == 1U) {
|
||||||
|
m_minFSWPtr = m_fswPtr + NXDN_FRAME_LENGTH_SAMPLES - 1U;
|
||||||
|
if (m_minFSWPtr >= NXDN_FRAME_LENGTH_SAMPLES)
|
||||||
|
m_minFSWPtr -= NXDN_FRAME_LENGTH_SAMPLES;
|
||||||
|
|
||||||
|
m_maxFSWPtr = m_fswPtr + 1U;
|
||||||
|
if (m_maxFSWPtr >= NXDN_FRAME_LENGTH_SAMPLES)
|
||||||
|
m_maxFSWPtr -= NXDN_FRAME_LENGTH_SAMPLES;
|
||||||
|
|
||||||
|
m_state = NXDNRXS_DATA;
|
||||||
|
m_countdown = 0U;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNXDNRX::processData(q15_t sample)
|
||||||
|
{
|
||||||
|
if (m_minFSWPtr < m_maxFSWPtr) {
|
||||||
|
if (m_dataPtr >= m_minFSWPtr && m_dataPtr <= m_maxFSWPtr)
|
||||||
|
correlateFSW();
|
||||||
|
} else {
|
||||||
|
if (m_dataPtr >= m_minFSWPtr || m_dataPtr <= m_maxFSWPtr)
|
||||||
|
correlateFSW();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_dataPtr == m_endPtr) {
|
||||||
|
// Only update the centre and threshold if they are from a good sync
|
||||||
|
if (m_lostCount == MAX_FSW_FRAMES) {
|
||||||
|
m_minFSWPtr = m_fswPtr + NXDN_FRAME_LENGTH_SAMPLES - 1U;
|
||||||
|
if (m_minFSWPtr >= NXDN_FRAME_LENGTH_SAMPLES)
|
||||||
|
m_minFSWPtr -= NXDN_FRAME_LENGTH_SAMPLES;
|
||||||
|
|
||||||
|
m_maxFSWPtr = m_fswPtr + 1U;
|
||||||
|
if (m_maxFSWPtr >= NXDN_FRAME_LENGTH_SAMPLES)
|
||||||
|
m_maxFSWPtr -= NXDN_FRAME_LENGTH_SAMPLES;
|
||||||
|
}
|
||||||
|
|
||||||
|
calculateLevels(m_startPtr, NXDN_FRAME_LENGTH_SYMBOLS);
|
||||||
|
|
||||||
|
DEBUG4("NXDNRX: sync found pos/centre/threshold", m_fswPtr, m_centreVal, m_thresholdVal);
|
||||||
|
|
||||||
|
uint8_t frame[NXDN_FRAME_LENGTH_BYTES + 3U];
|
||||||
|
samplesToBits(m_startPtr, NXDN_FRAME_LENGTH_SYMBOLS, frame, 8U, m_centreVal, m_thresholdVal);
|
||||||
|
|
||||||
|
// We've not seen a data sync for too long, signal RXLOST and change to RX_NONE
|
||||||
|
m_lostCount--;
|
||||||
|
if (m_lostCount == 0U) {
|
||||||
|
DEBUG1("NXDNRX: sync timed out, lost lock");
|
||||||
|
|
||||||
|
io.setDecode(false);
|
||||||
|
io.setADCDetection(false);
|
||||||
|
|
||||||
|
serial.writeNXDNLost();
|
||||||
|
|
||||||
|
m_state = NXDNRXS_NONE;
|
||||||
|
m_endPtr = NOENDPTR;
|
||||||
|
m_averagePtr = NOAVEPTR;
|
||||||
|
m_countdown = 0U;
|
||||||
|
m_maxCorr = 0;
|
||||||
|
} else {
|
||||||
|
frame[0U] = m_lostCount == (MAX_FSW_FRAMES - 1U) ? 0x01U : 0x00U;
|
||||||
|
writeRSSIData(frame);
|
||||||
|
m_maxCorr = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CNXDNRX::correlateFSW()
|
||||||
|
{
|
||||||
|
if (countBits32((m_bitBuffer[m_bitPtr] & NXDN_FSW_SYMBOLS_MASK) ^ NXDN_FSW_SYMBOLS) <= MAX_FSW_SYMBOLS_ERRS) {
|
||||||
|
uint16_t ptr = m_dataPtr + NXDN_FRAME_LENGTH_SAMPLES - NXDN_FSW_LENGTH_SAMPLES + NXDN_RADIO_SYMBOL_LENGTH;
|
||||||
|
if (ptr >= NXDN_FRAME_LENGTH_SAMPLES)
|
||||||
|
ptr -= NXDN_FRAME_LENGTH_SAMPLES;
|
||||||
|
|
||||||
|
q31_t corr = 0;
|
||||||
|
q15_t min = 16000;
|
||||||
|
q15_t max = -16000;
|
||||||
|
|
||||||
|
for (uint8_t i = 0U; i < NXDN_FSW_LENGTH_SYMBOLS; i++) {
|
||||||
|
q15_t val = m_buffer[ptr];
|
||||||
|
|
||||||
|
if (val > max)
|
||||||
|
max = val;
|
||||||
|
if (val < min)
|
||||||
|
min = val;
|
||||||
|
|
||||||
|
switch (NXDN_FSW_SYMBOLS_VALUES[i]) {
|
||||||
|
case +3:
|
||||||
|
corr -= (val + val + val);
|
||||||
|
break;
|
||||||
|
case +1:
|
||||||
|
corr -= val;
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
corr += val;
|
||||||
|
break;
|
||||||
|
default: // -3
|
||||||
|
corr += (val + val + val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr += NXDN_RADIO_SYMBOL_LENGTH;
|
||||||
|
if (ptr >= NXDN_FRAME_LENGTH_SAMPLES)
|
||||||
|
ptr -= NXDN_FRAME_LENGTH_SAMPLES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (corr > m_maxCorr) {
|
||||||
|
if (m_averagePtr == NOAVEPTR) {
|
||||||
|
m_centreVal = (max + min) >> 1;
|
||||||
|
|
||||||
|
q31_t v1 = (max - m_centreVal) * SCALING_FACTOR;
|
||||||
|
m_thresholdVal = q15_t(v1 >> 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t startPtr = m_dataPtr + NXDN_FRAME_LENGTH_SAMPLES - NXDN_FSW_LENGTH_SAMPLES + NXDN_RADIO_SYMBOL_LENGTH;
|
||||||
|
if (startPtr >= NXDN_FRAME_LENGTH_SAMPLES)
|
||||||
|
startPtr -= NXDN_FRAME_LENGTH_SAMPLES;
|
||||||
|
|
||||||
|
uint8_t sync[NXDN_FSW_BYTES_LENGTH];
|
||||||
|
samplesToBits(startPtr, NXDN_FSW_LENGTH_SYMBOLS, sync, 0U, m_centreVal, m_thresholdVal);
|
||||||
|
|
||||||
|
uint8_t maxErrs;
|
||||||
|
if (m_state == NXDNRXS_NONE)
|
||||||
|
maxErrs = MAX_FSW_BIT_START_ERRS;
|
||||||
|
else
|
||||||
|
maxErrs = MAX_FSW_BIT_RUN_ERRS;
|
||||||
|
|
||||||
|
uint8_t errs = 0U;
|
||||||
|
for (uint8_t i = 0U; i < NXDN_FSW_BYTES_LENGTH; i++)
|
||||||
|
errs += countBits8((sync[i] & NXDN_FSW_BYTES_MASK[i]) ^ NXDN_FSW_BYTES[i]);
|
||||||
|
|
||||||
|
if (errs <= maxErrs) {
|
||||||
|
m_maxCorr = corr;
|
||||||
|
m_lostCount = MAX_FSW_FRAMES;
|
||||||
|
m_fswPtr = m_dataPtr;
|
||||||
|
|
||||||
|
m_startPtr = startPtr;
|
||||||
|
|
||||||
|
m_endPtr = m_dataPtr + NXDN_FRAME_LENGTH_SAMPLES - NXDN_FSW_LENGTH_SAMPLES - 1U;
|
||||||
|
if (m_endPtr >= NXDN_FRAME_LENGTH_SAMPLES)
|
||||||
|
m_endPtr -= NXDN_FRAME_LENGTH_SAMPLES;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNXDNRX::calculateLevels(uint16_t start, uint16_t count)
|
||||||
|
{
|
||||||
|
q15_t maxPos = -16000;
|
||||||
|
q15_t minPos = 16000;
|
||||||
|
q15_t maxNeg = 16000;
|
||||||
|
q15_t minNeg = -16000;
|
||||||
|
|
||||||
|
for (uint16_t i = 0U; i < count; i++) {
|
||||||
|
q15_t sample = m_buffer[start];
|
||||||
|
|
||||||
|
if (sample > 0) {
|
||||||
|
if (sample > maxPos)
|
||||||
|
maxPos = sample;
|
||||||
|
if (sample < minPos)
|
||||||
|
minPos = sample;
|
||||||
|
} else {
|
||||||
|
if (sample < maxNeg)
|
||||||
|
maxNeg = sample;
|
||||||
|
if (sample > minNeg)
|
||||||
|
minNeg = sample;
|
||||||
|
}
|
||||||
|
|
||||||
|
start += NXDN_RADIO_SYMBOL_LENGTH;
|
||||||
|
if (start >= NXDN_FRAME_LENGTH_SAMPLES)
|
||||||
|
start -= NXDN_FRAME_LENGTH_SAMPLES;
|
||||||
|
}
|
||||||
|
|
||||||
|
q15_t posThresh = (maxPos + minPos) >> 1;
|
||||||
|
q15_t negThresh = (maxNeg + minNeg) >> 1;
|
||||||
|
|
||||||
|
q15_t centre = (posThresh + negThresh) >> 1;
|
||||||
|
|
||||||
|
q15_t threshold = posThresh - centre;
|
||||||
|
|
||||||
|
DEBUG5("NXDNRX: pos/neg/centre/threshold", posThresh, negThresh, centre, threshold);
|
||||||
|
|
||||||
|
if (m_averagePtr == NOAVEPTR) {
|
||||||
|
for (uint8_t i = 0U; i < 16U; i++) {
|
||||||
|
m_centre[i] = centre;
|
||||||
|
m_threshold[i] = threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_averagePtr = 0U;
|
||||||
|
} else {
|
||||||
|
m_centre[m_averagePtr] = centre;
|
||||||
|
m_threshold[m_averagePtr] = threshold;
|
||||||
|
|
||||||
|
m_averagePtr++;
|
||||||
|
if (m_averagePtr >= 16U)
|
||||||
|
m_averagePtr = 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_centreVal = 0;
|
||||||
|
m_thresholdVal = 0;
|
||||||
|
|
||||||
|
for (uint8_t i = 0U; i < 16U; i++) {
|
||||||
|
m_centreVal += m_centre[i];
|
||||||
|
m_thresholdVal += m_threshold[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
m_centreVal >>= 4;
|
||||||
|
m_thresholdVal >>= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNXDNRX::samplesToBits(uint16_t start, uint16_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold)
|
||||||
|
{
|
||||||
|
for (uint16_t i = 0U; i < count; i++) {
|
||||||
|
q15_t sample = m_buffer[start] - centre;
|
||||||
|
|
||||||
|
if (sample < -threshold) {
|
||||||
|
WRITE_BIT1(buffer, offset, false);
|
||||||
|
offset++;
|
||||||
|
WRITE_BIT1(buffer, offset, true);
|
||||||
|
offset++;
|
||||||
|
} else if (sample < 0) {
|
||||||
|
WRITE_BIT1(buffer, offset, false);
|
||||||
|
offset++;
|
||||||
|
WRITE_BIT1(buffer, offset, false);
|
||||||
|
offset++;
|
||||||
|
} else if (sample < threshold) {
|
||||||
|
WRITE_BIT1(buffer, offset, true);
|
||||||
|
offset++;
|
||||||
|
WRITE_BIT1(buffer, offset, false);
|
||||||
|
offset++;
|
||||||
|
} else {
|
||||||
|
WRITE_BIT1(buffer, offset, true);
|
||||||
|
offset++;
|
||||||
|
WRITE_BIT1(buffer, offset, true);
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
|
||||||
|
start += NXDN_RADIO_SYMBOL_LENGTH;
|
||||||
|
if (start >= NXDN_FRAME_LENGTH_SAMPLES)
|
||||||
|
start -= NXDN_FRAME_LENGTH_SAMPLES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNXDNRX::writeRSSIData(uint8_t* data)
|
||||||
|
{
|
||||||
|
#if defined(SEND_RSSI_DATA)
|
||||||
|
if (m_rssiCount > 0U) {
|
||||||
|
uint16_t rssi = m_rssiAccum / m_rssiCount;
|
||||||
|
|
||||||
|
data[49U] = (rssi >> 8) & 0xFFU;
|
||||||
|
data[50U] = (rssi >> 0) & 0xFFU;
|
||||||
|
|
||||||
|
serial.writeNXDNData(data, NXDN_FRAME_LENGTH_BYTES + 3U);
|
||||||
|
} else {
|
||||||
|
serial.writeNXDNData(data, NXDN_FRAME_LENGTH_BYTES + 1U);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
serial.writeNXDNData(data, NXDN_FRAME_LENGTH_BYTES + 1U);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_rssiAccum = 0U;
|
||||||
|
m_rssiCount = 0U;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
|
||||||
|
*
|
||||||
|
* 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(NXDNRX_H)
|
||||||
|
#define NXDNRX_H
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
#include "NXDNDefines.h"
|
||||||
|
|
||||||
|
enum NXDNRX_STATE {
|
||||||
|
NXDNRXS_NONE,
|
||||||
|
NXDNRXS_DATA
|
||||||
|
};
|
||||||
|
|
||||||
|
class CNXDNRX {
|
||||||
|
public:
|
||||||
|
CNXDNRX();
|
||||||
|
|
||||||
|
void samples(const q15_t* samples, uint16_t* rssi, uint8_t length);
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
NXDNRX_STATE m_state;
|
||||||
|
uint16_t m_bitBuffer[NXDN_RADIO_SYMBOL_LENGTH];
|
||||||
|
q15_t m_buffer[NXDN_FRAME_LENGTH_SAMPLES];
|
||||||
|
uint16_t m_bitPtr;
|
||||||
|
uint16_t m_dataPtr;
|
||||||
|
uint16_t m_startPtr;
|
||||||
|
uint16_t m_endPtr;
|
||||||
|
uint16_t m_fswPtr;
|
||||||
|
uint16_t m_minFSWPtr;
|
||||||
|
uint16_t m_maxFSWPtr;
|
||||||
|
q31_t m_maxCorr;
|
||||||
|
uint16_t m_lostCount;
|
||||||
|
uint8_t m_countdown;
|
||||||
|
q15_t m_centre[16U];
|
||||||
|
q15_t m_centreVal;
|
||||||
|
q15_t m_threshold[16U];
|
||||||
|
q15_t m_thresholdVal;
|
||||||
|
uint8_t m_averagePtr;
|
||||||
|
uint32_t m_rssiAccum;
|
||||||
|
uint16_t m_rssiCount;
|
||||||
|
|
||||||
|
void processNone(q15_t sample);
|
||||||
|
void processData(q15_t sample);
|
||||||
|
bool correlateFSW();
|
||||||
|
void calculateLevels(uint16_t start, uint16_t count);
|
||||||
|
void samplesToBits(uint16_t start, uint16_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold);
|
||||||
|
void writeRSSIData(uint8_t* data);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
+162
@@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2009-2018 by Jonathan Naylor G4KLX
|
||||||
|
* Copyright (C) 2017 by Andy Uribe CA6JAU
|
||||||
|
*
|
||||||
|
* 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
#include "Globals.h"
|
||||||
|
#include "NXDNTX.h"
|
||||||
|
|
||||||
|
#include "NXDNDefines.h"
|
||||||
|
|
||||||
|
// NXDN RRC filter + SINC filter
|
||||||
|
static q15_t RRC_0_2_FILTER[] = {51, 71, 92, 112, 129, 141, 144, 138, 120, 87, 39, -26, -107, -204, -314, -437, -567, -702, -835,
|
||||||
|
-932,-1066, -1176, -1257, -1304, -1314, -1284, -1213, -1099, -944, -749, -519, -257, 30, 335, 651,
|
||||||
|
968, 1277, 1569, 1832, 2058, 2237, 2360, 2420, 2412, 2329, 2170, 1935, 1623, 1239, 790, 283, -271,
|
||||||
|
-858, -1466, -2076, -2671, -3233, -3742, -4178, -4521, -4754, -4857, -4815, -4614, -4242, -3690,
|
||||||
|
-2952, -2025, -912, 385, 1855, 3488, 5266, 7172, 9183, 11274, 13418, 15585, 17746, 19869, 21923,
|
||||||
|
23876, 25700, 27364, 28844, 30116, 31159, 31956, 32495, 32767, 32767, 32495, 31956, 31159, 30116,
|
||||||
|
28844, 27364, 25700, 23876, 21923, 19869, 17746, 15585, 13418, 11274, 9183, 7172, 5266, 3488, 1855,
|
||||||
|
385, -912, -2025, -2952, -3690, -4242, -4614, -4815, -4857, -4754, -4521, -4178, -3742, -3233, -2671,
|
||||||
|
-2076, -1466, -858, -271, 283, 790, 1239, 1623, 1935, 2170, 2329, 2412, 2420, 2360, 2237, 2058, 1832,
|
||||||
|
1569, 1277, 968, 651, 335, 30, -257, -519, -749, -944, -1099, -1213, -1284, -1314, -1304, -1257,
|
||||||
|
-1176, -1066, -932, -835, -702, -567, -437, -314, -204, -107, -26, 39, 87, 120, 138, 144, 141, 129,
|
||||||
|
112, 92, 71, 51}; // numTaps = 180, L = 20
|
||||||
|
const uint16_t RRC_0_2_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L
|
||||||
|
|
||||||
|
const q15_t NXDN_LEVELA = 735;
|
||||||
|
const q15_t NXDN_LEVELB = 245;
|
||||||
|
const q15_t NXDN_LEVELC = -245;
|
||||||
|
const q15_t NXDN_LEVELD = -735;
|
||||||
|
|
||||||
|
const uint8_t NXDN_PREAMBLE[] = {0x57U, 0x75U, 0xFDU};
|
||||||
|
const uint8_t NXDN_SYNC = 0x5FU;
|
||||||
|
|
||||||
|
CNXDNTX::CNXDNTX() :
|
||||||
|
m_buffer(TX_BUFFER_LEN),
|
||||||
|
m_modFilter(),
|
||||||
|
m_modState(),
|
||||||
|
m_poBuffer(),
|
||||||
|
m_poLen(0U),
|
||||||
|
m_poPtr(0U),
|
||||||
|
m_txDelay(240U) // 200ms
|
||||||
|
{
|
||||||
|
::memset(m_modState, 0x00U, 16U * sizeof(q15_t));
|
||||||
|
|
||||||
|
m_modFilter.L = NXDN_RADIO_SYMBOL_LENGTH;
|
||||||
|
m_modFilter.phaseLength = RRC_0_2_FILTER_PHASE_LEN;
|
||||||
|
m_modFilter.pCoeffs = RRC_0_2_FILTER;
|
||||||
|
m_modFilter.pState = m_modState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNXDNTX::process()
|
||||||
|
{
|
||||||
|
if (m_buffer.getData() == 0U && m_poLen == 0U)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_poLen == 0U) {
|
||||||
|
if (!m_tx) {
|
||||||
|
for (uint16_t i = 0U; i < m_txDelay; i++)
|
||||||
|
m_poBuffer[m_poLen++] = NXDN_SYNC;
|
||||||
|
m_poBuffer[m_poLen++] = NXDN_PREAMBLE[0U];
|
||||||
|
m_poBuffer[m_poLen++] = NXDN_PREAMBLE[1U];
|
||||||
|
m_poBuffer[m_poLen++] = NXDN_PREAMBLE[2U];
|
||||||
|
} else {
|
||||||
|
for (uint8_t i = 0U; i < NXDN_FRAME_LENGTH_BYTES; i++) {
|
||||||
|
uint8_t c = m_buffer.get();
|
||||||
|
m_poBuffer[m_poLen++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_poPtr = 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_poLen > 0U) {
|
||||||
|
uint16_t space = io.getSpace();
|
||||||
|
|
||||||
|
while (space > (4U * NXDN_RADIO_SYMBOL_LENGTH)) {
|
||||||
|
uint8_t c = m_poBuffer[m_poPtr++];
|
||||||
|
writeByte(c);
|
||||||
|
|
||||||
|
space -= 4U * NXDN_RADIO_SYMBOL_LENGTH;
|
||||||
|
|
||||||
|
if (m_poPtr >= m_poLen) {
|
||||||
|
m_poPtr = 0U;
|
||||||
|
m_poLen = 0U;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t CNXDNTX::writeData(const uint8_t* data, uint8_t length)
|
||||||
|
{
|
||||||
|
if (length != (NXDN_FRAME_LENGTH_BYTES + 1U))
|
||||||
|
return 4U;
|
||||||
|
|
||||||
|
uint16_t space = m_buffer.getSpace();
|
||||||
|
if (space < NXDN_FRAME_LENGTH_BYTES)
|
||||||
|
return 5U;
|
||||||
|
|
||||||
|
for (uint8_t i = 0U; i < NXDN_FRAME_LENGTH_BYTES; i++)
|
||||||
|
m_buffer.put(data[i + 1U]);
|
||||||
|
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNXDNTX::writeByte(uint8_t c)
|
||||||
|
{
|
||||||
|
q15_t inBuffer[4U];
|
||||||
|
q15_t outBuffer[NXDN_RADIO_SYMBOL_LENGTH * 4U];
|
||||||
|
|
||||||
|
const uint8_t MASK = 0xC0U;
|
||||||
|
|
||||||
|
for (uint8_t i = 0U; i < 4U; i++, c <<= 2) {
|
||||||
|
switch (c & MASK) {
|
||||||
|
case 0xC0U:
|
||||||
|
inBuffer[i] = NXDN_LEVELA;
|
||||||
|
break;
|
||||||
|
case 0x80U:
|
||||||
|
inBuffer[i] = NXDN_LEVELB;
|
||||||
|
break;
|
||||||
|
case 0x00U:
|
||||||
|
inBuffer[i] = NXDN_LEVELC;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
inBuffer[i] = NXDN_LEVELD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::arm_fir_interpolate_q15(&m_modFilter, inBuffer, outBuffer, 4U);
|
||||||
|
|
||||||
|
io.write(STATE_NXDN, outBuffer, NXDN_RADIO_SYMBOL_LENGTH * 4U);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNXDNTX::setTXDelay(uint8_t delay)
|
||||||
|
{
|
||||||
|
m_txDelay = 300U + uint16_t(delay) * 6U; // 500ms + tx delay
|
||||||
|
|
||||||
|
if (m_txDelay > 1200U)
|
||||||
|
m_txDelay = 1200U;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t CNXDNTX::getSpace() const
|
||||||
|
{
|
||||||
|
return m_buffer.getSpace() / NXDN_FRAME_LENGTH_BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
|
||||||
|
*
|
||||||
|
* 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(NXDNTX_H)
|
||||||
|
#define NXDNTX_H
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
|
#include "SerialRB.h"
|
||||||
|
|
||||||
|
class CNXDNTX {
|
||||||
|
public:
|
||||||
|
CNXDNTX();
|
||||||
|
|
||||||
|
uint8_t writeData(const uint8_t* data, uint8_t length);
|
||||||
|
|
||||||
|
void process();
|
||||||
|
|
||||||
|
void setTXDelay(uint8_t delay);
|
||||||
|
|
||||||
|
uint8_t getSpace() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
CSerialRB m_buffer;
|
||||||
|
arm_fir_interpolate_instance_q15 m_modFilter;
|
||||||
|
q15_t m_modState[16U]; // blockSize + phaseLength - 1, 4 + 9 - 1 plus some spare
|
||||||
|
uint8_t m_poBuffer[1200U];
|
||||||
|
uint16_t m_poLen;
|
||||||
|
uint16_t m_poPtr;
|
||||||
|
uint16_t m_txDelay;
|
||||||
|
|
||||||
|
void writeByte(uint8_t c);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
+27
-4
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX
|
||||||
|
* Copyright (C) 2018 by Bryan Biedenkapp <[email protected]>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,30 +20,42 @@
|
|||||||
#if !defined(P25DEFINES_H)
|
#if !defined(P25DEFINES_H)
|
||||||
#define P25DEFINES_H
|
#define P25DEFINES_H
|
||||||
|
|
||||||
const unsigned int P25_RADIO_SYMBOL_LENGTH = 5U; // At 24 kHz sample rate
|
const unsigned int P25_RADIO_SYMBOL_LENGTH = 10U; // At 48 kHz sample rate
|
||||||
|
|
||||||
const unsigned int P25_HDR_FRAME_LENGTH_BYTES = 99U;
|
const unsigned int P25_HDR_FRAME_LENGTH_BYTES = 99U;
|
||||||
const unsigned int P25_HDR_FRAME_LENGTH_BITS = P25_HDR_FRAME_LENGTH_BYTES * 8U;
|
const unsigned int P25_HDR_FRAME_LENGTH_BITS = P25_HDR_FRAME_LENGTH_BYTES * 8U;
|
||||||
const unsigned int P25_HDR_FRAME_LENGTH_SYMBOLS = P25_HDR_FRAME_LENGTH_BYTES * 4U;
|
const unsigned int P25_HDR_FRAME_LENGTH_SYMBOLS = P25_HDR_FRAME_LENGTH_BYTES * 4U;
|
||||||
|
const unsigned int P25_HDR_FRAME_LENGTH_SAMPLES = P25_HDR_FRAME_LENGTH_SYMBOLS * P25_RADIO_SYMBOL_LENGTH;
|
||||||
|
|
||||||
const unsigned int P25_LDU_FRAME_LENGTH_BYTES = 216U;
|
const unsigned int P25_LDU_FRAME_LENGTH_BYTES = 216U;
|
||||||
const unsigned int P25_LDU_FRAME_LENGTH_BITS = P25_LDU_FRAME_LENGTH_BYTES * 8U;
|
const unsigned int P25_LDU_FRAME_LENGTH_BITS = P25_LDU_FRAME_LENGTH_BYTES * 8U;
|
||||||
const unsigned int P25_LDU_FRAME_LENGTH_SYMBOLS = P25_LDU_FRAME_LENGTH_BYTES * 4U;
|
const unsigned int P25_LDU_FRAME_LENGTH_SYMBOLS = P25_LDU_FRAME_LENGTH_BYTES * 4U;
|
||||||
|
const unsigned int P25_LDU_FRAME_LENGTH_SAMPLES = P25_LDU_FRAME_LENGTH_SYMBOLS * P25_RADIO_SYMBOL_LENGTH;
|
||||||
|
|
||||||
const unsigned int P25_TERMLC_FRAME_LENGTH_BYTES = 54U;
|
const unsigned int P25_TERMLC_FRAME_LENGTH_BYTES = 54U;
|
||||||
const unsigned int P25_TERMLC_FRAME_LENGTH_BITS = P25_TERMLC_FRAME_LENGTH_BYTES * 8U;
|
const unsigned int P25_TERMLC_FRAME_LENGTH_BITS = P25_TERMLC_FRAME_LENGTH_BYTES * 8U;
|
||||||
const unsigned int P25_TERMLC_FRAME_LENGTH_SYMBOLS = P25_TERMLC_FRAME_LENGTH_BYTES * 4U;
|
const unsigned int P25_TERMLC_FRAME_LENGTH_SYMBOLS = P25_TERMLC_FRAME_LENGTH_BYTES * 4U;
|
||||||
|
const unsigned int P25_TERMLC_FRAME_LENGTH_SAMPLES = P25_TERMLC_FRAME_LENGTH_SYMBOLS * P25_RADIO_SYMBOL_LENGTH;
|
||||||
|
|
||||||
const unsigned int P25_TERM_FRAME_LENGTH_BYTES = 18U;
|
const unsigned int P25_TERM_FRAME_LENGTH_BYTES = 18U;
|
||||||
const unsigned int P25_TERM_FRAME_LENGTH_BITS = P25_TERM_FRAME_LENGTH_BYTES * 8U;
|
const unsigned int P25_TERM_FRAME_LENGTH_BITS = P25_TERM_FRAME_LENGTH_BYTES * 8U;
|
||||||
const unsigned int P25_TERM_FRAME_LENGTH_SYMBOLS = P25_TERM_FRAME_LENGTH_BYTES * 4U;
|
const unsigned int P25_TERM_FRAME_LENGTH_SYMBOLS = P25_TERM_FRAME_LENGTH_BYTES * 4U;
|
||||||
|
const unsigned int P25_TERM_FRAME_LENGTH_SAMPLES = P25_TERM_FRAME_LENGTH_SYMBOLS * P25_RADIO_SYMBOL_LENGTH;
|
||||||
|
|
||||||
|
const unsigned int P25_TSDU_FRAME_LENGTH_BYTES = 45U;
|
||||||
|
const unsigned int P25_TSDU_FRAME_LENGTH_BITS = P25_TSDU_FRAME_LENGTH_BYTES * 8U;
|
||||||
|
const unsigned int P25_TSDU_FRAME_LENGTH_SYMBOLS = P25_TSDU_FRAME_LENGTH_BYTES * 4U;
|
||||||
|
const unsigned int P25_TSDU_FRAME_LENGTH_SAMPLES = P25_TSDU_FRAME_LENGTH_SYMBOLS * P25_RADIO_SYMBOL_LENGTH;
|
||||||
|
|
||||||
const unsigned int P25_SYNC_LENGTH_BYTES = 6U;
|
const unsigned int P25_SYNC_LENGTH_BYTES = 6U;
|
||||||
const unsigned int P25_SYNC_LENGTH_BITS = P25_SYNC_LENGTH_BYTES * 8U;
|
const unsigned int P25_SYNC_LENGTH_BITS = P25_SYNC_LENGTH_BYTES * 8U;
|
||||||
const unsigned int P25_SYNC_LENGTH_SYMBOLS = P25_SYNC_LENGTH_BYTES * 4U;
|
const unsigned int P25_SYNC_LENGTH_SYMBOLS = P25_SYNC_LENGTH_BYTES * 4U;
|
||||||
|
const unsigned int P25_SYNC_LENGTH_SAMPLES = P25_SYNC_LENGTH_SYMBOLS * P25_RADIO_SYMBOL_LENGTH;
|
||||||
|
|
||||||
const unsigned int P25_NID_LENGTH_BITS = 64U;
|
const unsigned int P25_NID_LENGTH_BYTES = 8U;
|
||||||
const unsigned int P25_NID_LENGTH_SYMBOLS = 32U;
|
const unsigned int P25_NID_LENGTH_BITS = P25_NID_LENGTH_BYTES * 8U;
|
||||||
|
const unsigned int P25_NID_LENGTH_SYMBOLS = P25_NID_LENGTH_BYTES * 4U;
|
||||||
|
const unsigned int P25_NID_LENGTH_SAMPLES = P25_NID_LENGTH_SYMBOLS * P25_RADIO_SYMBOL_LENGTH;
|
||||||
|
|
||||||
const uint8_t P25_SYNC_BYTES[] = {0x55U, 0x75U, 0xF5U, 0xFFU, 0x77U, 0xFFU};
|
const uint8_t P25_SYNC_BYTES[] = {0x55U, 0x75U, 0xF5U, 0xFFU, 0x77U, 0xFFU};
|
||||||
const uint8_t P25_SYNC_BYTES_LENGTH = 6U;
|
const uint8_t P25_SYNC_BYTES_LENGTH = 6U;
|
||||||
@@ -54,8 +67,18 @@ const uint64_t P25_SYNC_BITS_MASK = 0x0000FFFFFFFFFFFFU;
|
|||||||
// 01 01 01 01 01 11 01 01 11 11 01 01 11 11 11 11 01 11 01 11 11 11 11 11
|
// 01 01 01 01 01 11 01 01 11 11 01 01 11 11 11 11 01 11 01 11 11 11 11 11
|
||||||
// +3 +3 +3 +3 +3 -3 +3 +3 -3 -3 +3 +3 -3 -3 -3 -3 +3 -3 +3 -3 -3 -3 -3 -3
|
// +3 +3 +3 +3 +3 -3 +3 +3 -3 -3 +3 +3 -3 -3 -3 -3 +3 -3 +3 -3 -3 -3 -3 -3
|
||||||
|
|
||||||
|
const int8_t P25_SYNC_SYMBOLS_VALUES[] = {+3, +3, +3, +3, +3, -3, +3, +3, -3, -3, +3, +3, -3, -3, -3, -3, +3, -3, +3, -3, -3, -3, -3, -3};
|
||||||
|
|
||||||
const uint32_t P25_SYNC_SYMBOLS = 0x00FB30A0U;
|
const uint32_t P25_SYNC_SYMBOLS = 0x00FB30A0U;
|
||||||
const uint32_t P25_SYNC_SYMBOLS_MASK = 0x00FFFFFFU;
|
const uint32_t P25_SYNC_SYMBOLS_MASK = 0x00FFFFFFU;
|
||||||
|
|
||||||
|
const uint8_t P25_DUID_HDU = 0x00U; // Header Data Unit
|
||||||
|
const uint8_t P25_DUID_TDU = 0x03U; // Simple Terminator Data Unit
|
||||||
|
const uint8_t P25_DUID_LDU1 = 0x05U; // Logical Link Data Unit 1
|
||||||
|
const uint8_t P25_DUID_TSDU = 0x07U; // Trunking System Data Unit
|
||||||
|
const uint8_t P25_DUID_LDU2 = 0x0AU; // Logical Link Data Unit 2
|
||||||
|
const uint8_t P25_DUID_PDU = 0x0CU; // Packet Data Unit
|
||||||
|
const uint8_t P25_DUID_TDULC = 0x0FU; // Terminator Data Unit with Link Control
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2009-2017 by Jonathan Naylor G4KLX
|
||||||
|
* Copyright (C) 2018 by Bryan Biedenkapp <[email protected]>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -16,227 +17,270 @@
|
|||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// #define WANT_DEBUG
|
|
||||||
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "P25RX.h"
|
#include "P25RX.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
const unsigned int BUFFER_LENGTH = 200U;
|
const q15_t SCALING_FACTOR = 18750; // Q15(0.57)
|
||||||
|
|
||||||
const q15_t SCALING_FACTOR = 18750; // Q15(0.55)
|
const uint8_t CORRELATION_COUNTDOWN = 10U;//5U;
|
||||||
|
|
||||||
const uint32_t PLLMAX = 0x10000U;
|
const uint8_t MAX_SYNC_BIT_START_ERRS = 2U;
|
||||||
const uint32_t PLLINC = PLLMAX / P25_RADIO_SYMBOL_LENGTH;
|
const uint8_t MAX_SYNC_BIT_RUN_ERRS = 4U;
|
||||||
const uint32_t INC = PLLINC / 32U;
|
|
||||||
|
|
||||||
const uint8_t SYNC_SYMBOL_ERRS = 0U;
|
const uint8_t MAX_SYNC_SYMBOLS_ERRS = 2U;
|
||||||
|
|
||||||
const uint8_t SYNC_BIT_START_ERRS = 2U;
|
const uint8_t BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U };
|
||||||
const uint8_t SYNC_BIT_RUN_ERRS = 4U;
|
|
||||||
|
|
||||||
const unsigned int MAX_SYNC_FRAMES = 3U + 1U;
|
|
||||||
|
|
||||||
const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
|
||||||
|
|
||||||
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
||||||
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
|
||||||
|
const uint8_t NOAVEPTR = 99U;
|
||||||
|
|
||||||
|
const uint16_t NOENDPTR = 9999U;
|
||||||
|
|
||||||
|
const unsigned int MAX_SYNC_FRAMES = 4U + 1U;
|
||||||
|
|
||||||
CP25RX::CP25RX() :
|
CP25RX::CP25RX() :
|
||||||
m_pll(0U),
|
|
||||||
m_prev(false),
|
|
||||||
m_state(P25RXS_NONE),
|
m_state(P25RXS_NONE),
|
||||||
m_bitBuffer(0x00U),
|
m_bitBuffer(),
|
||||||
m_symbols(),
|
m_buffer(),
|
||||||
m_outBuffer(),
|
m_bitPtr(0U),
|
||||||
m_buffer(NULL),
|
m_dataPtr(0U),
|
||||||
m_bufferPtr(0U),
|
m_hdrStartPtr(NOENDPTR),
|
||||||
m_symbolPtr(0U),
|
m_lduStartPtr(NOENDPTR),
|
||||||
|
m_lduEndPtr(NOENDPTR),
|
||||||
|
m_minSyncPtr(NOENDPTR),
|
||||||
|
m_maxSyncPtr(NOENDPTR),
|
||||||
|
m_hdrSyncPtr(NOENDPTR),
|
||||||
|
m_lduSyncPtr(NOENDPTR),
|
||||||
|
m_maxCorr(0),
|
||||||
m_lostCount(0U),
|
m_lostCount(0U),
|
||||||
m_centre(0),
|
m_countdown(0U),
|
||||||
m_threshold(0)
|
m_centre(),
|
||||||
|
m_centreVal(0),
|
||||||
|
m_threshold(),
|
||||||
|
m_thresholdVal(0),
|
||||||
|
m_averagePtr(NOAVEPTR),
|
||||||
|
m_rssiAccum(0U),
|
||||||
|
m_rssiCount(0U),
|
||||||
|
m_duid(0U)
|
||||||
{
|
{
|
||||||
m_buffer = m_outBuffer + 1U;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CP25RX::reset()
|
void CP25RX::reset()
|
||||||
{
|
{
|
||||||
m_pll = 0U;
|
m_state = P25RXS_NONE;
|
||||||
m_prev = false;
|
m_dataPtr = 0U;
|
||||||
m_state = P25RXS_NONE;
|
m_bitPtr = 0U;
|
||||||
m_bitBuffer = 0x00U;
|
m_maxCorr = 0;
|
||||||
m_bufferPtr = 0U;
|
m_averagePtr = NOAVEPTR;
|
||||||
m_symbolPtr = 0U;
|
m_hdrStartPtr = NOENDPTR;
|
||||||
m_lostCount = 0U;
|
m_lduStartPtr = NOENDPTR;
|
||||||
m_centre = 0;
|
m_lduEndPtr = NOENDPTR;
|
||||||
m_threshold = 0;
|
m_hdrSyncPtr = NOENDPTR;
|
||||||
|
m_lduSyncPtr = NOENDPTR;
|
||||||
|
m_minSyncPtr = NOENDPTR;
|
||||||
|
m_maxSyncPtr = NOENDPTR;
|
||||||
|
m_centreVal = 0;
|
||||||
|
m_thresholdVal = 0;
|
||||||
|
m_lostCount = 0U;
|
||||||
|
m_countdown = 0U;
|
||||||
|
m_rssiAccum = 0U;
|
||||||
|
m_rssiCount = 0U;
|
||||||
|
m_duid = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CP25RX::samples(const q15_t* samples, uint8_t length)
|
void CP25RX::samples(const q15_t* samples, uint16_t* rssi, uint8_t length)
|
||||||
{
|
{
|
||||||
for (uint16_t i = 0U; i < length; i++) {
|
for (uint8_t i = 0U; i < length; i++) {
|
||||||
bool bit = samples[i] < 0;
|
q15_t sample = samples[i];
|
||||||
|
|
||||||
if (bit != m_prev) {
|
m_rssiAccum += rssi[i];
|
||||||
if (m_pll < (PLLMAX / 2U))
|
m_rssiCount++;
|
||||||
m_pll += INC;
|
|
||||||
else
|
m_bitBuffer[m_bitPtr] <<= 1;
|
||||||
m_pll -= INC;
|
if (sample < 0)
|
||||||
|
m_bitBuffer[m_bitPtr] |= 0x01U;
|
||||||
|
|
||||||
|
m_buffer[m_dataPtr] = sample;
|
||||||
|
|
||||||
|
switch (m_state) {
|
||||||
|
case P25RXS_HDR:
|
||||||
|
processHdr(sample);
|
||||||
|
break;
|
||||||
|
case P25RXS_LDU:
|
||||||
|
processLdu(sample);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
processNone(sample);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_prev = bit;
|
m_dataPtr++;
|
||||||
|
if (m_dataPtr >= P25_LDU_FRAME_LENGTH_SAMPLES) {
|
||||||
m_pll += PLLINC;
|
m_dataPtr = 0U;
|
||||||
|
m_duid = 0U;
|
||||||
if (m_pll >= PLLMAX) {
|
|
||||||
m_pll -= PLLMAX;
|
|
||||||
|
|
||||||
if (m_state == P25RXS_NONE)
|
|
||||||
processNone(samples[i]);
|
|
||||||
else
|
|
||||||
processData(samples[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_bitPtr++;
|
||||||
|
if (m_bitPtr >= P25_RADIO_SYMBOL_LENGTH)
|
||||||
|
m_bitPtr = 0U;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CP25RX::processNone(q15_t sample)
|
void CP25RX::processNone(q15_t sample)
|
||||||
{
|
{
|
||||||
m_symbolBuffer <<= 1;
|
bool ret = correlateSync();
|
||||||
if (sample < 0)
|
if (ret) {
|
||||||
m_symbolBuffer |= 0x01U;
|
// On the first sync, start the countdown to the state change
|
||||||
|
if (m_countdown == 0U) {
|
||||||
m_symbols[m_symbolPtr] = sample;
|
m_rssiAccum = 0U;
|
||||||
|
m_rssiCount = 0U;
|
||||||
// Fuzzy matching of the data sync bit sequence
|
|
||||||
if (countBits32((m_symbolBuffer & P25_SYNC_SYMBOLS_MASK) ^ P25_SYNC_SYMBOLS) <= SYNC_SYMBOL_ERRS) {
|
|
||||||
q15_t max = -16000;
|
|
||||||
q15_t min = 16000;
|
|
||||||
|
|
||||||
for (uint8_t i = 0U; i < P25_SYNC_LENGTH_SYMBOLS; i++) {
|
|
||||||
q15_t val = m_symbols[i];
|
|
||||||
if (val > max)
|
|
||||||
max = val;
|
|
||||||
if (val < min)
|
|
||||||
min = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
q15_t centre = (max + min) >> 1;
|
|
||||||
|
|
||||||
q31_t v1 = (max - centre) * SCALING_FACTOR;
|
|
||||||
q15_t threshold = q15_t(v1 >> 15);
|
|
||||||
|
|
||||||
uint16_t ptr = m_symbolPtr + 1U;
|
|
||||||
if (ptr >= P25_SYNC_LENGTH_SYMBOLS)
|
|
||||||
ptr = 0U;
|
|
||||||
|
|
||||||
for (uint8_t i = 0U; i < P25_SYNC_LENGTH_SYMBOLS; i++) {
|
|
||||||
q15_t sample = m_symbols[ptr] - centre;
|
|
||||||
|
|
||||||
if (sample < -threshold) {
|
|
||||||
m_bitBuffer <<= 2;
|
|
||||||
m_bitBuffer |= 0x01U;
|
|
||||||
} else if (sample < 0) {
|
|
||||||
m_bitBuffer <<= 2;
|
|
||||||
m_bitBuffer |= 0x00U;
|
|
||||||
} else if (sample < threshold) {
|
|
||||||
m_bitBuffer <<= 2;
|
|
||||||
m_bitBuffer |= 0x02U;
|
|
||||||
} else {
|
|
||||||
m_bitBuffer <<= 2;
|
|
||||||
m_bitBuffer |= 0x03U;
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr++;
|
|
||||||
if (ptr >= P25_SYNC_LENGTH_SYMBOLS)
|
|
||||||
ptr = 0U;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fuzzy matching of the data sync bit sequence
|
|
||||||
if (countBits64((m_bitBuffer & P25_SYNC_BITS_MASK) ^ P25_SYNC_BITS) <= SYNC_BIT_START_ERRS) {
|
|
||||||
DEBUG5("P25RX: sync found in None min/max/centre/threshold", min, max, centre, threshold);
|
|
||||||
for (uint8_t i = 0U; i < P25_SYNC_LENGTH_BYTES; i++)
|
|
||||||
m_buffer[i] = P25_SYNC_BYTES[i];
|
|
||||||
m_centre = centre;
|
|
||||||
m_threshold = threshold;
|
|
||||||
m_lostCount = MAX_SYNC_FRAMES;
|
|
||||||
m_bufferPtr = P25_SYNC_LENGTH_BITS;
|
|
||||||
m_state = P25RXS_DATA;
|
|
||||||
|
|
||||||
io.setDecode(true);
|
io.setDecode(true);
|
||||||
io.setADCDetection(true);
|
io.setADCDetection(true);
|
||||||
|
|
||||||
|
m_averagePtr = NOAVEPTR;
|
||||||
|
|
||||||
|
m_countdown = CORRELATION_COUNTDOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_symbolPtr++;
|
if (m_countdown > 0U)
|
||||||
if (m_symbolPtr >= P25_SYNC_LENGTH_SYMBOLS)
|
m_countdown--;
|
||||||
m_symbolPtr = 0U;
|
|
||||||
|
if (m_countdown == 1U) {
|
||||||
|
// These are the sync positions for the following LDU after a HDR
|
||||||
|
m_minSyncPtr = m_hdrSyncPtr + P25_HDR_FRAME_LENGTH_SAMPLES - 1U;
|
||||||
|
if (m_minSyncPtr >= P25_LDU_FRAME_LENGTH_SAMPLES)
|
||||||
|
m_minSyncPtr -= P25_LDU_FRAME_LENGTH_SAMPLES;
|
||||||
|
|
||||||
|
m_maxSyncPtr = m_hdrSyncPtr + P25_HDR_FRAME_LENGTH_SAMPLES + 1U;
|
||||||
|
if (m_maxSyncPtr >= P25_LDU_FRAME_LENGTH_SAMPLES)
|
||||||
|
m_maxSyncPtr -= P25_LDU_FRAME_LENGTH_SAMPLES;
|
||||||
|
|
||||||
|
m_state = P25RXS_HDR;
|
||||||
|
m_countdown = 0U;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CP25RX::processData(q15_t sample)
|
void CP25RX::processHdr(q15_t sample)
|
||||||
{
|
{
|
||||||
sample -= m_centre;
|
if (m_minSyncPtr < m_maxSyncPtr) {
|
||||||
|
if (m_dataPtr >= m_minSyncPtr && m_dataPtr <= m_maxSyncPtr)
|
||||||
if (sample < -m_threshold) {
|
correlateSync();
|
||||||
m_bitBuffer <<= 2;
|
|
||||||
m_bitBuffer |= 0x01U;
|
|
||||||
WRITE_BIT1(m_buffer, m_bufferPtr, false);
|
|
||||||
m_bufferPtr++;
|
|
||||||
WRITE_BIT1(m_buffer, m_bufferPtr, true);
|
|
||||||
m_bufferPtr++;
|
|
||||||
} else if (sample < 0) {
|
|
||||||
m_bitBuffer <<= 2;
|
|
||||||
m_bitBuffer |= 0x00U;
|
|
||||||
WRITE_BIT1(m_buffer, m_bufferPtr, false);
|
|
||||||
m_bufferPtr++;
|
|
||||||
WRITE_BIT1(m_buffer, m_bufferPtr, false);
|
|
||||||
m_bufferPtr++;
|
|
||||||
} else if (sample < m_threshold) {
|
|
||||||
m_bitBuffer <<= 2;
|
|
||||||
m_bitBuffer |= 0x02U;
|
|
||||||
WRITE_BIT1(m_buffer, m_bufferPtr, true);
|
|
||||||
m_bufferPtr++;
|
|
||||||
WRITE_BIT1(m_buffer, m_bufferPtr, false);
|
|
||||||
m_bufferPtr++;
|
|
||||||
} else {
|
} else {
|
||||||
m_bitBuffer <<= 2;
|
if (m_dataPtr >= m_minSyncPtr || m_dataPtr <= m_maxSyncPtr)
|
||||||
m_bitBuffer |= 0x03U;
|
correlateSync();
|
||||||
WRITE_BIT1(m_buffer, m_bufferPtr, true);
|
|
||||||
m_bufferPtr++;
|
|
||||||
WRITE_BIT1(m_buffer, m_bufferPtr, true);
|
|
||||||
m_bufferPtr++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search for an early sync to indicate an LDU following a header
|
if (m_dataPtr == m_maxSyncPtr) {
|
||||||
if (m_bufferPtr >= (P25_HDR_FRAME_LENGTH_BITS + P25_SYNC_LENGTH_BITS - 1U) && m_bufferPtr <= (P25_HDR_FRAME_LENGTH_BITS + P25_SYNC_LENGTH_BITS + 1U)) {
|
uint16_t nidStartPtr = m_hdrStartPtr + P25_SYNC_LENGTH_SAMPLES;
|
||||||
// Fuzzy matching of the data sync bit sequence
|
if (nidStartPtr >= P25_LDU_FRAME_LENGTH_SAMPLES)
|
||||||
if (countBits64((m_bitBuffer & P25_SYNC_BITS_MASK) ^ P25_SYNC_BITS) <= SYNC_BIT_RUN_ERRS) {
|
nidStartPtr -= P25_LDU_FRAME_LENGTH_SAMPLES;
|
||||||
DEBUG2("P25RX: found LDU sync in Data, pos", m_bufferPtr - P25_SYNC_LENGTH_BITS);
|
|
||||||
|
|
||||||
m_outBuffer[0U] = 0x01U;
|
uint8_t nid[2U];
|
||||||
serial.writeP25Hdr(m_outBuffer, P25_HDR_FRAME_LENGTH_BYTES + 1U);
|
samplesToBits(nidStartPtr, (2U * 4U), nid, 0U, m_centreVal, m_thresholdVal);
|
||||||
|
// DEBUG3("P25RX: nid (b0 - b1)", nid[0U], nid[1U]);
|
||||||
|
|
||||||
// Restore the sync that's now in the wrong place
|
m_duid = nid[1U] & 0x0F;
|
||||||
for (uint8_t i = 0U; i < P25_SYNC_LENGTH_BYTES; i++)
|
|
||||||
m_buffer[i] = P25_SYNC_BYTES[i];
|
|
||||||
|
|
||||||
m_lostCount = MAX_SYNC_FRAMES;
|
switch (m_duid) {
|
||||||
m_bufferPtr = P25_SYNC_LENGTH_BITS;
|
case P25_DUID_HDU: {
|
||||||
|
calculateLevels(m_hdrStartPtr, P25_HDR_FRAME_LENGTH_SYMBOLS);
|
||||||
|
|
||||||
|
DEBUG4("P25RX: sync found in Hdr pos/centre/threshold", m_hdrSyncPtr, m_centreVal, m_thresholdVal);
|
||||||
|
|
||||||
|
uint8_t frame[P25_HDR_FRAME_LENGTH_BYTES + 1U];
|
||||||
|
samplesToBits(m_hdrStartPtr, P25_HDR_FRAME_LENGTH_SYMBOLS, frame, 8U, m_centreVal, m_thresholdVal);
|
||||||
|
|
||||||
|
frame[0U] = 0x01U;
|
||||||
|
serial.writeP25Hdr(frame, P25_HDR_FRAME_LENGTH_BYTES + 1U);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case P25_DUID_TSDU: {
|
||||||
|
calculateLevels(m_hdrStartPtr, P25_TSDU_FRAME_LENGTH_SYMBOLS);
|
||||||
|
|
||||||
|
DEBUG4("P25RX: sync found in TSDU pos/centre/threshold", m_hdrSyncPtr, m_centreVal, m_thresholdVal);
|
||||||
|
|
||||||
|
uint8_t frame[P25_TSDU_FRAME_LENGTH_BYTES + 1U];
|
||||||
|
samplesToBits(m_hdrStartPtr, P25_TSDU_FRAME_LENGTH_SYMBOLS, frame, 8U, m_centreVal, m_thresholdVal);
|
||||||
|
|
||||||
|
frame[0U] = 0x01U;
|
||||||
|
serial.writeP25Hdr(frame, P25_TSDU_FRAME_LENGTH_BYTES + 1U);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case P25_DUID_TDU: {
|
||||||
|
calculateLevels(m_hdrStartPtr, P25_TERM_FRAME_LENGTH_SYMBOLS);
|
||||||
|
|
||||||
|
DEBUG4("P25RX: sync found in TDU pos/centre/threshold", m_hdrSyncPtr, m_centreVal, m_thresholdVal);
|
||||||
|
|
||||||
|
uint8_t frame[P25_TERM_FRAME_LENGTH_BYTES + 1U];
|
||||||
|
samplesToBits(m_hdrStartPtr, P25_TERM_FRAME_LENGTH_SYMBOLS, frame, 8U, m_centreVal, m_thresholdVal);
|
||||||
|
|
||||||
|
frame[0U] = 0x01U;
|
||||||
|
serial.writeP25Hdr(frame, P25_TERM_FRAME_LENGTH_BYTES + 1U);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case P25_DUID_TDULC: {
|
||||||
|
calculateLevels(m_hdrStartPtr, P25_TERMLC_FRAME_LENGTH_SYMBOLS);
|
||||||
|
|
||||||
|
DEBUG4("P25RX: sync found in TDULC pos/centre/threshold", m_hdrSyncPtr, m_centreVal, m_thresholdVal);
|
||||||
|
|
||||||
|
uint8_t frame[P25_TERMLC_FRAME_LENGTH_BYTES + 1U];
|
||||||
|
samplesToBits(m_hdrStartPtr, P25_TERMLC_FRAME_LENGTH_SYMBOLS, frame, 8U, m_centreVal, m_thresholdVal);
|
||||||
|
|
||||||
|
frame[0U] = 0x01U;
|
||||||
|
serial.writeP25Hdr(frame, P25_TERMLC_FRAME_LENGTH_BYTES + 1U);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_minSyncPtr = m_lduSyncPtr + P25_LDU_FRAME_LENGTH_SAMPLES - 1U;
|
||||||
|
if (m_minSyncPtr >= P25_LDU_FRAME_LENGTH_SAMPLES)
|
||||||
|
m_minSyncPtr -= P25_LDU_FRAME_LENGTH_SAMPLES;
|
||||||
|
|
||||||
|
m_maxSyncPtr = m_lduSyncPtr + 1U;
|
||||||
|
if (m_maxSyncPtr >= P25_LDU_FRAME_LENGTH_SAMPLES)
|
||||||
|
m_maxSyncPtr -= P25_LDU_FRAME_LENGTH_SAMPLES;
|
||||||
|
|
||||||
|
m_state = P25RXS_LDU;
|
||||||
|
m_maxCorr = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CP25RX::processLdu(q15_t sample)
|
||||||
|
{
|
||||||
|
if (m_minSyncPtr < m_maxSyncPtr) {
|
||||||
|
if (m_dataPtr >= m_minSyncPtr && m_dataPtr <= m_maxSyncPtr)
|
||||||
|
correlateSync();
|
||||||
|
} else {
|
||||||
|
if (m_dataPtr >= m_minSyncPtr || m_dataPtr <= m_maxSyncPtr)
|
||||||
|
correlateSync();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only search for a sync in the right place +-2 symbols
|
if (m_dataPtr == m_lduEndPtr) {
|
||||||
if (m_bufferPtr >= (P25_SYNC_LENGTH_BITS - 2U) && m_bufferPtr <= (P25_SYNC_LENGTH_BITS + 2U)) {
|
// Only update the centre and threshold if they are from a good sync
|
||||||
// Fuzzy matching of the data sync bit sequence
|
if (m_lostCount == MAX_SYNC_FRAMES) {
|
||||||
if (countBits64((m_bitBuffer & P25_SYNC_BITS_MASK) ^ P25_SYNC_BITS) <= SYNC_BIT_RUN_ERRS) {
|
m_minSyncPtr = m_lduSyncPtr + P25_LDU_FRAME_LENGTH_SAMPLES - 1U;
|
||||||
DEBUG2("P25RX: found sync in Data, pos", m_bufferPtr - P25_SYNC_LENGTH_BITS);
|
if (m_minSyncPtr >= P25_LDU_FRAME_LENGTH_SAMPLES)
|
||||||
m_lostCount = MAX_SYNC_FRAMES;
|
m_minSyncPtr -= P25_LDU_FRAME_LENGTH_SAMPLES;
|
||||||
m_bufferPtr = P25_SYNC_LENGTH_BITS;
|
|
||||||
|
m_maxSyncPtr = m_lduSyncPtr + 1U;
|
||||||
|
if (m_maxSyncPtr >= P25_LDU_FRAME_LENGTH_SAMPLES)
|
||||||
|
m_maxSyncPtr -= P25_LDU_FRAME_LENGTH_SAMPLES;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Send a data frame to the host if the required number of bits have been received
|
calculateLevels(m_lduStartPtr, P25_LDU_FRAME_LENGTH_SYMBOLS);
|
||||||
if (m_bufferPtr == P25_LDU_FRAME_LENGTH_BITS) {
|
|
||||||
|
DEBUG4("P25RX: sync found in Ldu pos/centre/threshold", m_lduSyncPtr, m_centreVal, m_thresholdVal);
|
||||||
|
|
||||||
|
uint8_t frame[P25_LDU_FRAME_LENGTH_BYTES + 3U];
|
||||||
|
samplesToBits(m_lduStartPtr, P25_LDU_FRAME_LENGTH_SYMBOLS, frame, 8U, m_centreVal, m_thresholdVal);
|
||||||
|
|
||||||
// We've not seen a data sync for too long, signal RXLOST and change to RX_NONE
|
// We've not seen a data sync for too long, signal RXLOST and change to RX_NONE
|
||||||
m_lostCount--;
|
m_lostCount--;
|
||||||
if (m_lostCount == 0U) {
|
if (m_lostCount == 0U) {
|
||||||
@@ -247,16 +291,235 @@ void CP25RX::processData(q15_t sample)
|
|||||||
|
|
||||||
serial.writeP25Lost();
|
serial.writeP25Lost();
|
||||||
|
|
||||||
m_state = P25RXS_NONE;
|
m_state = P25RXS_NONE;
|
||||||
} else {
|
m_lduEndPtr = NOENDPTR;
|
||||||
m_outBuffer[0U] = m_lostCount == (MAX_SYNC_FRAMES - 1U) ? 0x01U : 0x00U;
|
m_averagePtr = NOAVEPTR;
|
||||||
|
m_countdown = 0U;
|
||||||
serial.writeP25Ldu(m_outBuffer, P25_LDU_FRAME_LENGTH_BYTES + 1U);
|
m_maxCorr = 0;
|
||||||
|
m_duid = 0U;
|
||||||
// Start the next frame
|
} else {
|
||||||
::memset(m_outBuffer, 0x00U, P25_LDU_FRAME_LENGTH_BYTES + 3U);
|
frame[0U] = m_lostCount == (MAX_SYNC_FRAMES - 1U) ? 0x01U : 0x00U;
|
||||||
m_bufferPtr = 0U;
|
writeRSSILdu(frame);
|
||||||
|
m_maxCorr = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CP25RX::correlateSync()
|
||||||
|
{
|
||||||
|
if (countBits32((m_bitBuffer[m_bitPtr] & P25_SYNC_SYMBOLS_MASK) ^ P25_SYNC_SYMBOLS) <= MAX_SYNC_SYMBOLS_ERRS) {
|
||||||
|
uint16_t ptr = m_dataPtr + P25_LDU_FRAME_LENGTH_SAMPLES - P25_SYNC_LENGTH_SAMPLES + P25_RADIO_SYMBOL_LENGTH;
|
||||||
|
if (ptr >= P25_LDU_FRAME_LENGTH_SAMPLES)
|
||||||
|
ptr -= P25_LDU_FRAME_LENGTH_SAMPLES;
|
||||||
|
|
||||||
|
q31_t corr = 0;
|
||||||
|
q15_t min = 16000;
|
||||||
|
q15_t max = -16000;
|
||||||
|
|
||||||
|
for (uint8_t i = 0U; i < P25_SYNC_LENGTH_SYMBOLS; i++) {
|
||||||
|
q15_t val = m_buffer[ptr];
|
||||||
|
|
||||||
|
if (val > max)
|
||||||
|
max = val;
|
||||||
|
if (val < min)
|
||||||
|
min = val;
|
||||||
|
|
||||||
|
switch (P25_SYNC_SYMBOLS_VALUES[i]) {
|
||||||
|
case +3:
|
||||||
|
corr -= (val + val + val);
|
||||||
|
break;
|
||||||
|
case +1:
|
||||||
|
corr -= val;
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
corr += val;
|
||||||
|
break;
|
||||||
|
default: // -3
|
||||||
|
corr += (val + val + val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr += P25_RADIO_SYMBOL_LENGTH;
|
||||||
|
if (ptr >= P25_LDU_FRAME_LENGTH_SAMPLES)
|
||||||
|
ptr -= P25_LDU_FRAME_LENGTH_SAMPLES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (corr > m_maxCorr) {
|
||||||
|
if (m_averagePtr == NOAVEPTR) {
|
||||||
|
m_centreVal = (max + min) >> 1;
|
||||||
|
|
||||||
|
q31_t v1 = (max - m_centreVal) * SCALING_FACTOR;
|
||||||
|
m_thresholdVal = q15_t(v1 >> 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t startPtr = m_dataPtr + P25_LDU_FRAME_LENGTH_SAMPLES - P25_SYNC_LENGTH_SAMPLES + P25_RADIO_SYMBOL_LENGTH;
|
||||||
|
if (startPtr >= P25_LDU_FRAME_LENGTH_SAMPLES)
|
||||||
|
startPtr -= P25_LDU_FRAME_LENGTH_SAMPLES;
|
||||||
|
|
||||||
|
uint8_t sync[P25_SYNC_BYTES_LENGTH];
|
||||||
|
samplesToBits(startPtr, P25_SYNC_LENGTH_SYMBOLS, sync, 0U, m_centreVal, m_thresholdVal);
|
||||||
|
|
||||||
|
uint8_t maxErrs;
|
||||||
|
if (m_state == P25RXS_NONE)
|
||||||
|
maxErrs = MAX_SYNC_BIT_START_ERRS;
|
||||||
|
else
|
||||||
|
maxErrs = MAX_SYNC_BIT_RUN_ERRS;
|
||||||
|
|
||||||
|
uint8_t errs = 0U;
|
||||||
|
for (uint8_t i = 0U; i < P25_SYNC_BYTES_LENGTH; i++)
|
||||||
|
errs += countBits8(sync[i] ^ P25_SYNC_BYTES[i]);
|
||||||
|
|
||||||
|
if (errs <= maxErrs) {
|
||||||
|
m_maxCorr = corr;
|
||||||
|
m_lostCount = MAX_SYNC_FRAMES;
|
||||||
|
|
||||||
|
m_lduSyncPtr = m_dataPtr;
|
||||||
|
|
||||||
|
// These are the positions of the start and end of an LDU
|
||||||
|
m_lduStartPtr = startPtr;
|
||||||
|
|
||||||
|
m_lduEndPtr = m_dataPtr + P25_LDU_FRAME_LENGTH_SAMPLES - P25_SYNC_LENGTH_SAMPLES - 1U;
|
||||||
|
if (m_lduEndPtr >= P25_LDU_FRAME_LENGTH_SAMPLES)
|
||||||
|
m_lduEndPtr -= P25_LDU_FRAME_LENGTH_SAMPLES;
|
||||||
|
|
||||||
|
if (m_state == P25RXS_NONE) {
|
||||||
|
m_hdrSyncPtr = m_dataPtr;
|
||||||
|
|
||||||
|
// This is the position of the start of a HDR
|
||||||
|
m_hdrStartPtr = startPtr;
|
||||||
|
|
||||||
|
// These are the range of positions for a sync for an LDU following a HDR
|
||||||
|
m_minSyncPtr = m_dataPtr + P25_HDR_FRAME_LENGTH_SAMPLES - 1U;
|
||||||
|
if (m_minSyncPtr >= P25_LDU_FRAME_LENGTH_SAMPLES)
|
||||||
|
m_minSyncPtr -= P25_LDU_FRAME_LENGTH_SAMPLES;
|
||||||
|
|
||||||
|
m_maxSyncPtr = m_dataPtr + P25_HDR_FRAME_LENGTH_SAMPLES + 1U;
|
||||||
|
if (m_maxSyncPtr >= P25_LDU_FRAME_LENGTH_SAMPLES)
|
||||||
|
m_maxSyncPtr -= P25_LDU_FRAME_LENGTH_SAMPLES;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CP25RX::calculateLevels(uint16_t start, uint16_t count)
|
||||||
|
{
|
||||||
|
q15_t maxPos = -16000;
|
||||||
|
q15_t minPos = 16000;
|
||||||
|
q15_t maxNeg = 16000;
|
||||||
|
q15_t minNeg = -16000;
|
||||||
|
|
||||||
|
for (uint16_t i = 0U; i < count; i++) {
|
||||||
|
q15_t sample = m_buffer[start];
|
||||||
|
|
||||||
|
if (sample > 0) {
|
||||||
|
if (sample > maxPos)
|
||||||
|
maxPos = sample;
|
||||||
|
if (sample < minPos)
|
||||||
|
minPos = sample;
|
||||||
|
} else {
|
||||||
|
if (sample < maxNeg)
|
||||||
|
maxNeg = sample;
|
||||||
|
if (sample > minNeg)
|
||||||
|
minNeg = sample;
|
||||||
|
}
|
||||||
|
|
||||||
|
start += P25_RADIO_SYMBOL_LENGTH;
|
||||||
|
if (start >= P25_LDU_FRAME_LENGTH_SAMPLES)
|
||||||
|
start -= P25_LDU_FRAME_LENGTH_SAMPLES;
|
||||||
|
}
|
||||||
|
|
||||||
|
q15_t posThresh = (maxPos + minPos) >> 1;
|
||||||
|
q15_t negThresh = (maxNeg + minNeg) >> 1;
|
||||||
|
|
||||||
|
q15_t centre = (posThresh + negThresh) >> 1;
|
||||||
|
|
||||||
|
q15_t threshold = posThresh - centre;
|
||||||
|
|
||||||
|
DEBUG5("P25RX: pos/neg/centre/threshold", posThresh, negThresh, centre, threshold);
|
||||||
|
|
||||||
|
if (m_averagePtr == NOAVEPTR) {
|
||||||
|
for (uint8_t i = 0U; i < 16U; i++) {
|
||||||
|
m_centre[i] = centre;
|
||||||
|
m_threshold[i] = threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_averagePtr = 0U;
|
||||||
|
} else {
|
||||||
|
m_centre[m_averagePtr] = centre;
|
||||||
|
m_threshold[m_averagePtr] = threshold;
|
||||||
|
|
||||||
|
m_averagePtr++;
|
||||||
|
if (m_averagePtr >= 16U)
|
||||||
|
m_averagePtr = 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_centreVal = 0;
|
||||||
|
m_thresholdVal = 0;
|
||||||
|
|
||||||
|
for (uint8_t i = 0U; i < 16U; i++) {
|
||||||
|
m_centreVal += m_centre[i];
|
||||||
|
m_thresholdVal += m_threshold[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
m_centreVal >>= 4;
|
||||||
|
m_thresholdVal >>= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CP25RX::samplesToBits(uint16_t start, uint16_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold)
|
||||||
|
{
|
||||||
|
for (uint16_t i = 0U; i < count; i++) {
|
||||||
|
q15_t sample = m_buffer[start] - centre;
|
||||||
|
|
||||||
|
if (sample < -threshold) {
|
||||||
|
WRITE_BIT1(buffer, offset, false);
|
||||||
|
offset++;
|
||||||
|
WRITE_BIT1(buffer, offset, true);
|
||||||
|
offset++;
|
||||||
|
} else if (sample < 0) {
|
||||||
|
WRITE_BIT1(buffer, offset, false);
|
||||||
|
offset++;
|
||||||
|
WRITE_BIT1(buffer, offset, false);
|
||||||
|
offset++;
|
||||||
|
} else if (sample < threshold) {
|
||||||
|
WRITE_BIT1(buffer, offset, true);
|
||||||
|
offset++;
|
||||||
|
WRITE_BIT1(buffer, offset, false);
|
||||||
|
offset++;
|
||||||
|
} else {
|
||||||
|
WRITE_BIT1(buffer, offset, true);
|
||||||
|
offset++;
|
||||||
|
WRITE_BIT1(buffer, offset, true);
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
|
||||||
|
start += P25_RADIO_SYMBOL_LENGTH;
|
||||||
|
if (start >= P25_LDU_FRAME_LENGTH_SAMPLES)
|
||||||
|
start -= P25_LDU_FRAME_LENGTH_SAMPLES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CP25RX::writeRSSILdu(uint8_t* ldu)
|
||||||
|
{
|
||||||
|
#if defined(SEND_RSSI_DATA)
|
||||||
|
if (m_rssiCount > 0U) {
|
||||||
|
uint16_t rssi = m_rssiAccum / m_rssiCount;
|
||||||
|
|
||||||
|
ldu[217U] = (rssi >> 8) & 0xFFU;
|
||||||
|
ldu[218U] = (rssi >> 0) & 0xFFU;
|
||||||
|
|
||||||
|
serial.writeP25Ldu(ldu, P25_LDU_FRAME_LENGTH_BYTES + 3U);
|
||||||
|
} else {
|
||||||
|
serial.writeP25Ldu(ldu, P25_LDU_FRAME_LENGTH_BYTES + 1U);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
serial.writeP25Ldu(ldu, P25_LDU_FRAME_LENGTH_BYTES + 1U);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_rssiAccum = 0U;
|
||||||
|
m_rssiCount = 0U;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
|
||||||
|
* Copyright (C) 2018 by Bryan Biedenkapp <[email protected]>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -24,35 +25,50 @@
|
|||||||
|
|
||||||
enum P25RX_STATE {
|
enum P25RX_STATE {
|
||||||
P25RXS_NONE,
|
P25RXS_NONE,
|
||||||
P25RXS_DATA
|
P25RXS_HDR,
|
||||||
|
P25RXS_LDU
|
||||||
};
|
};
|
||||||
|
|
||||||
class CP25RX {
|
class CP25RX {
|
||||||
public:
|
public:
|
||||||
CP25RX();
|
CP25RX();
|
||||||
|
|
||||||
void samples(const q15_t* samples, uint8_t length);
|
void samples(const q15_t* samples, uint16_t* rssi, uint8_t length);
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t m_pll;
|
|
||||||
bool m_prev;
|
|
||||||
P25RX_STATE m_state;
|
P25RX_STATE m_state;
|
||||||
uint32_t m_symbolBuffer;
|
uint32_t m_bitBuffer[P25_RADIO_SYMBOL_LENGTH];
|
||||||
uint64_t m_bitBuffer;
|
q15_t m_buffer[P25_LDU_FRAME_LENGTH_SAMPLES];
|
||||||
q15_t m_symbols[P25_SYNC_LENGTH_SYMBOLS];
|
uint16_t m_bitPtr;
|
||||||
uint8_t m_outBuffer[P25_LDU_FRAME_LENGTH_BYTES + 3U];
|
uint16_t m_dataPtr;
|
||||||
uint8_t* m_buffer;
|
uint16_t m_hdrStartPtr;
|
||||||
uint16_t m_bufferPtr;
|
uint16_t m_lduStartPtr;
|
||||||
uint16_t m_symbolPtr;
|
uint16_t m_lduEndPtr;
|
||||||
|
uint16_t m_minSyncPtr;
|
||||||
|
uint16_t m_maxSyncPtr;
|
||||||
|
uint16_t m_hdrSyncPtr;
|
||||||
|
uint16_t m_lduSyncPtr;
|
||||||
|
q31_t m_maxCorr;
|
||||||
uint16_t m_lostCount;
|
uint16_t m_lostCount;
|
||||||
q15_t m_centre;
|
uint8_t m_countdown;
|
||||||
q15_t m_threshold;
|
q15_t m_centre[16U];
|
||||||
|
q15_t m_centreVal;
|
||||||
|
q15_t m_threshold[16U];
|
||||||
|
q15_t m_thresholdVal;
|
||||||
|
uint8_t m_averagePtr;
|
||||||
|
uint32_t m_rssiAccum;
|
||||||
|
uint16_t m_rssiCount;
|
||||||
|
uint8_t m_duid;
|
||||||
|
|
||||||
void processNone(q15_t sample);
|
void processNone(q15_t sample);
|
||||||
void processData(q15_t sample);
|
void processHdr(q15_t sample);
|
||||||
|
void processLdu(q15_t sample);
|
||||||
|
bool correlateSync();
|
||||||
|
void calculateLevels(uint16_t start, uint16_t count);
|
||||||
|
void samplesToBits(uint16_t start, uint16_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold);
|
||||||
|
void writeRSSILdu(uint8_t* ldu);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX
|
||||||
|
* Copyright (C) 2017 by Andy Uribe CA6JAU
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -16,45 +17,39 @@
|
|||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// #define WANT_DEBUG
|
|
||||||
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "P25TX.h"
|
#include "P25TX.h"
|
||||||
|
|
||||||
#include "P25Defines.h"
|
#include "P25Defines.h"
|
||||||
|
|
||||||
#if defined(WIDE_C4FSK_FILTERS_TX)
|
// Generated using rcosdesign(0.2, 8, 10, 'normal') in MATLAB
|
||||||
// Generated using rcosdesign(0.2, 4, 5, 'sqrt') in MATLAB
|
static q15_t RC_0_2_FILTER[] = {-444, -897, -1311, -1636, -1825, -1840, -1659, -1278, -712, 0,
|
||||||
static q15_t P25_C4FSK_FILTER[] = {688, -680, -2158, -3060, -2724, -775, 2684, 7041, 11310, 14425, 15565, 14425,
|
800, 1613, 2354, 2936, 3277, 3310, 2994, 2315, 1296, 0, -1478,
|
||||||
11310, 7041, 2684, -775, -2724, -3060, -2158, -680, 688, 0};
|
-3011, -4448, -5627, -6386, -6580, -6090, -4839, -2800, 0, 3474,
|
||||||
const uint16_t P25_C4FSK_FILTER_LEN = 22U;
|
7482, 11835, 16311, 20666, 24651, 28032, 30607, 32219, 32767,
|
||||||
#else
|
32219, 30607, 28032, 24651, 20666, 16311, 11835, 7482, 3474, 0,
|
||||||
// Generated using rcosdesign(0.2, 8, 5, 'sqrt') in MATLAB
|
-2800, -4839, -6090, -6580, -6386, -5627, -4448, -3011, -1478,
|
||||||
static q15_t P25_C4FSK_FILTER[] = {401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995,
|
0, 1296, 2315, 2994, 3310, 3277, 2936, 2354, 1613, 800, 0, -712,
|
||||||
11237, 14331, 15464, 14331, 11237, 6995, 2667, -770, -2706, -3040, -2144, -675, 683, 1450, 1472, 909, 112,
|
-1278, -1659, -1840, -1825, -1636, -1311, -897, -444, 0}; // numTaps = 80, L = 10
|
||||||
-553, -847, -731, -340, 104, 401, 0};
|
const uint16_t RC_0_2_FILTER_PHASE_LEN = 8U; // phaseLength = numTaps/L
|
||||||
const uint16_t P25_C4FSK_FILTER_LEN = 42U;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Generated in MATLAB using the following commands, and then normalised for unity gain
|
// Generated in MATLAB using the following commands, and then normalised for unity gain
|
||||||
// shape2 = 'Inverse-sinc Lowpass';
|
// shape2 = 'Inverse-sinc Lowpass';
|
||||||
// d2 = fdesign.interpolator(2, shape2);
|
// d2 = fdesign.interpolator(1, shape2);
|
||||||
// h2 = design(d2, 'SystemObject', true);
|
// h2 = design(d2, 'SystemObject', true);
|
||||||
static q15_t P25_LP_FILTER[] = {170, 401, 340, -203, -715, -478, 281, 419, -440, -1002, -103, 1114, 528, -1389, -1520, 1108, 2674, -388, -4662,
|
static q15_t LOWPASS_FILTER[] = {1294, -2251, 4312, -8402, 20999, 20999, -8402, 4312, -2251, 1294};
|
||||||
-2132, 9168, 20241, 20241, 9168, -2132, -4662, -388, 2674, 1108, -1520, -1389, 528, 1114, -103, -1002, -440, 419,
|
const uint16_t LOWPASS_FILTER_LEN = 10U;
|
||||||
281, -478, -715, -203, 340, 401, 170};
|
|
||||||
const uint16_t P25_LP_FILTER_LEN = 44U;
|
|
||||||
|
|
||||||
const q15_t P25_LEVELA[] = { 495, 495, 495, 495, 495};
|
const q15_t P25_LEVELA = 1260;
|
||||||
const q15_t P25_LEVELB[] = { 165, 165, 165, 165, 165};
|
const q15_t P25_LEVELB = 420;
|
||||||
const q15_t P25_LEVELC[] = {-165, -165, -165, -165, -165};
|
const q15_t P25_LEVELC = -420;
|
||||||
const q15_t P25_LEVELD[] = {-495, -495, -495, -495, -495};
|
const q15_t P25_LEVELD = -1260;
|
||||||
|
|
||||||
const uint8_t P25_START_SYNC = 0x77U;
|
const uint8_t P25_START_SYNC = 0x77U;
|
||||||
|
|
||||||
CP25TX::CP25TX() :
|
CP25TX::CP25TX() :
|
||||||
m_buffer(1500U),
|
m_buffer(TX_BUFFER_LEN),
|
||||||
m_modFilter(),
|
m_modFilter(),
|
||||||
m_lpFilter(),
|
m_lpFilter(),
|
||||||
m_modState(),
|
m_modState(),
|
||||||
@@ -62,19 +57,19 @@ m_lpState(),
|
|||||||
m_poBuffer(),
|
m_poBuffer(),
|
||||||
m_poLen(0U),
|
m_poLen(0U),
|
||||||
m_poPtr(0U),
|
m_poPtr(0U),
|
||||||
m_txDelay(240U), // 200ms
|
m_txDelay(240U) // 200ms
|
||||||
m_count(0U)
|
|
||||||
{
|
{
|
||||||
::memset(m_modState, 0x00U, 70U * sizeof(q15_t));
|
::memset(m_modState, 0x00U, 16U * sizeof(q15_t));
|
||||||
::memset(m_lpState, 0x00U, 70U * sizeof(q15_t));
|
::memset(m_lpState, 0x00U, 60U * sizeof(q15_t));
|
||||||
|
|
||||||
m_modFilter.numTaps = P25_C4FSK_FILTER_LEN;
|
m_modFilter.L = P25_RADIO_SYMBOL_LENGTH;
|
||||||
m_modFilter.pState = m_modState;
|
m_modFilter.phaseLength = RC_0_2_FILTER_PHASE_LEN;
|
||||||
m_modFilter.pCoeffs = P25_C4FSK_FILTER;
|
m_modFilter.pCoeffs = RC_0_2_FILTER;
|
||||||
|
m_modFilter.pState = m_modState;
|
||||||
|
|
||||||
m_lpFilter.numTaps = P25_LP_FILTER_LEN;
|
m_lpFilter.numTaps = LOWPASS_FILTER_LEN;
|
||||||
m_lpFilter.pState = m_lpState;
|
m_lpFilter.pState = m_lpState;
|
||||||
m_lpFilter.pCoeffs = P25_LP_FILTER;
|
m_lpFilter.pCoeffs = LOWPASS_FILTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CP25TX::process()
|
void CP25TX::process()
|
||||||
@@ -84,8 +79,6 @@ void CP25TX::process()
|
|||||||
|
|
||||||
if (m_poLen == 0U) {
|
if (m_poLen == 0U) {
|
||||||
if (!m_tx) {
|
if (!m_tx) {
|
||||||
m_count = 0U;
|
|
||||||
|
|
||||||
for (uint16_t i = 0U; i < m_txDelay; i++)
|
for (uint16_t i = 0U; i < m_txDelay; i++)
|
||||||
m_poBuffer[m_poLen++] = P25_START_SYNC;
|
m_poBuffer[m_poLen++] = P25_START_SYNC;
|
||||||
} else {
|
} else {
|
||||||
@@ -135,61 +128,45 @@ uint8_t CP25TX::writeData(const uint8_t* data, uint8_t length)
|
|||||||
|
|
||||||
void CP25TX::writeByte(uint8_t c)
|
void CP25TX::writeByte(uint8_t c)
|
||||||
{
|
{
|
||||||
q15_t inBuffer[P25_RADIO_SYMBOL_LENGTH * 4U + 1U];
|
q15_t inBuffer[4U];
|
||||||
q15_t intBuffer[P25_RADIO_SYMBOL_LENGTH * 4U + 1U];
|
q15_t intBuffer[P25_RADIO_SYMBOL_LENGTH * 4U];
|
||||||
q15_t outBuffer[P25_RADIO_SYMBOL_LENGTH * 4U + 1U];
|
q15_t outBuffer[P25_RADIO_SYMBOL_LENGTH * 4U];
|
||||||
|
|
||||||
const uint8_t MASK = 0xC0U;
|
const uint8_t MASK = 0xC0U;
|
||||||
|
|
||||||
q15_t* p = inBuffer;
|
for (uint8_t i = 0U; i < 4U; i++, c <<= 2) {
|
||||||
for (uint8_t i = 0U; i < 4U; i++, c <<= 2, p += P25_RADIO_SYMBOL_LENGTH) {
|
|
||||||
switch (c & MASK) {
|
switch (c & MASK) {
|
||||||
case 0xC0U:
|
case 0xC0U:
|
||||||
::memcpy(p, P25_LEVELA, P25_RADIO_SYMBOL_LENGTH * sizeof(q15_t));
|
inBuffer[i] = P25_LEVELA;
|
||||||
break;
|
break;
|
||||||
case 0x80U:
|
case 0x80U:
|
||||||
::memcpy(p, P25_LEVELB, P25_RADIO_SYMBOL_LENGTH * sizeof(q15_t));
|
inBuffer[i] = P25_LEVELB;
|
||||||
break;
|
break;
|
||||||
case 0x00U:
|
case 0x00U:
|
||||||
::memcpy(p, P25_LEVELC, P25_RADIO_SYMBOL_LENGTH * sizeof(q15_t));
|
inBuffer[i] = P25_LEVELC;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
::memcpy(p, P25_LEVELD, P25_RADIO_SYMBOL_LENGTH * sizeof(q15_t));
|
inBuffer[i] = P25_LEVELD;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t blockSize = P25_RADIO_SYMBOL_LENGTH * 4U;
|
::arm_fir_interpolate_q15(&m_modFilter, inBuffer, intBuffer, 4U);
|
||||||
|
|
||||||
// Handle the case of the oscillator not being accurate enough
|
::arm_fir_fast_q15(&m_lpFilter, intBuffer, outBuffer, P25_RADIO_SYMBOL_LENGTH * 4U);
|
||||||
if (m_sampleCount > 0U) {
|
|
||||||
m_count += P25_RADIO_SYMBOL_LENGTH * 4U;
|
|
||||||
|
|
||||||
if (m_count >= m_sampleCount) {
|
io.write(STATE_P25, outBuffer, P25_RADIO_SYMBOL_LENGTH * 4U);
|
||||||
if (m_sampleInsert) {
|
|
||||||
inBuffer[P25_RADIO_SYMBOL_LENGTH * 4U] = inBuffer[P25_RADIO_SYMBOL_LENGTH * 4U - 1U];
|
|
||||||
blockSize++;
|
|
||||||
} else {
|
|
||||||
blockSize--;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_count -= m_sampleCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::arm_fir_fast_q15(&m_modFilter, inBuffer, intBuffer, blockSize);
|
|
||||||
|
|
||||||
::arm_fir_fast_q15(&m_lpFilter, intBuffer, outBuffer, blockSize);
|
|
||||||
|
|
||||||
io.write(STATE_P25, outBuffer, blockSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CP25TX::setTXDelay(uint8_t delay)
|
void CP25TX::setTXDelay(uint8_t delay)
|
||||||
{
|
{
|
||||||
m_txDelay = 600U + uint16_t(delay) * 12U; // 500ms + tx delay
|
m_txDelay = 600U + uint16_t(delay) * 12U; // 500ms + tx delay
|
||||||
|
|
||||||
|
if (m_txDelay > 1200U)
|
||||||
|
m_txDelay = 1200U;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t CP25TX::getSpace() const
|
uint8_t CP25TX::getSpace() const
|
||||||
{
|
{
|
||||||
return m_buffer.getSpace() / P25_LDU_FRAME_LENGTH_BYTES;
|
return m_buffer.getSpace() / P25_LDU_FRAME_LENGTH_BYTES;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -33,19 +33,18 @@ public:
|
|||||||
|
|
||||||
void setTXDelay(uint8_t delay);
|
void setTXDelay(uint8_t delay);
|
||||||
|
|
||||||
uint16_t getSpace() const;
|
uint8_t getSpace() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CSerialRB m_buffer;
|
CSerialRB m_buffer;
|
||||||
arm_fir_instance_q15 m_modFilter;
|
arm_fir_interpolate_instance_q15 m_modFilter;
|
||||||
arm_fir_instance_q15 m_lpFilter;
|
arm_fir_instance_q15 m_lpFilter;
|
||||||
q15_t m_modState[70U]; // NoTaps + BlockSize - 1, 42 + 20 - 1 plus some spare
|
q15_t m_modState[16U]; // blockSize + phaseLength - 1, 4 + 9 - 1 plus some spare
|
||||||
q15_t m_lpState[70U]; // NoTaps + BlockSize - 1, 44 + 20 - 1 plus some spare
|
q15_t m_lpState[60U]; // NoTaps + BlockSize - 1, 32 + 20 - 1 plus some spare
|
||||||
uint8_t m_poBuffer[920U];
|
uint8_t m_poBuffer[1200U];
|
||||||
uint16_t m_poLen;
|
uint16_t m_poLen;
|
||||||
uint16_t m_poPtr;
|
uint16_t m_poPtr;
|
||||||
uint16_t m_txDelay;
|
uint16_t m_txDelay;
|
||||||
uint32_t m_count;
|
|
||||||
|
|
||||||
void writeByte(uint8_t c);
|
void writeByte(uint8_t c);
|
||||||
};
|
};
|
||||||
|
|||||||
+149
@@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2009-2018 by Jonathan Naylor G4KLX
|
||||||
|
*
|
||||||
|
* 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
#include "Globals.h"
|
||||||
|
#include "POCSAGTX.h"
|
||||||
|
|
||||||
|
const uint16_t POCSAG_FRAME_LENGTH_BYTES = 17U * sizeof(uint32_t);
|
||||||
|
|
||||||
|
const uint16_t POCSAG_PREAMBLE_LENGTH_BYTES = 18U * sizeof(uint32_t);
|
||||||
|
|
||||||
|
const uint16_t POCSAG_RADIO_SYMBOL_LENGTH = 40U; // at 48Khz
|
||||||
|
|
||||||
|
const q15_t POCSAG_LEVEL1[] = { 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700};
|
||||||
|
const q15_t POCSAG_LEVEL0[] = {-1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700};
|
||||||
|
|
||||||
|
static q15_t SHAPING_FILTER[] = {2730, 2730, 2730, 2730, 2730, 2730, 2730, 2730, 2730, 2730, 2730, 2730};
|
||||||
|
const uint16_t SHAPING_FILTER_LEN = 12U;
|
||||||
|
|
||||||
|
const uint8_t POCSAG_SYNC = 0xAAU;
|
||||||
|
|
||||||
|
CPOCSAGTX::CPOCSAGTX() :
|
||||||
|
m_buffer(TX_BUFFER_LEN),
|
||||||
|
m_modFilter(),
|
||||||
|
m_modState(),
|
||||||
|
m_poBuffer(),
|
||||||
|
m_poLen(0U),
|
||||||
|
m_poPtr(0U),
|
||||||
|
m_txDelay(POCSAG_PREAMBLE_LENGTH_BYTES)
|
||||||
|
{
|
||||||
|
::memset(m_modState, 0x00U, 180U * sizeof(q15_t));
|
||||||
|
|
||||||
|
m_modFilter.numTaps = SHAPING_FILTER_LEN;
|
||||||
|
m_modFilter.pState = m_modState;
|
||||||
|
m_modFilter.pCoeffs = SHAPING_FILTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPOCSAGTX::process()
|
||||||
|
{
|
||||||
|
if (m_buffer.getData() == 0U && m_poLen == 0U)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_poLen == 0U) {
|
||||||
|
if (!m_tx) {
|
||||||
|
for (uint16_t i = 0U; i < m_txDelay; i++)
|
||||||
|
m_poBuffer[m_poLen++] = POCSAG_SYNC;
|
||||||
|
} else {
|
||||||
|
for (uint8_t i = 0U; i < POCSAG_FRAME_LENGTH_BYTES; i++) {
|
||||||
|
uint8_t c = m_buffer.get();
|
||||||
|
m_poBuffer[m_poLen++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_poPtr = 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_poLen > 0U) {
|
||||||
|
uint16_t space = io.getSpace();
|
||||||
|
|
||||||
|
while (space > (8U * POCSAG_RADIO_SYMBOL_LENGTH)) {
|
||||||
|
uint8_t c = m_poBuffer[m_poPtr++];
|
||||||
|
writeByte(c);
|
||||||
|
|
||||||
|
space -= 8U * POCSAG_RADIO_SYMBOL_LENGTH;
|
||||||
|
|
||||||
|
if (m_poPtr >= m_poLen) {
|
||||||
|
m_poPtr = 0U;
|
||||||
|
m_poLen = 0U;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPOCSAGTX::busy()
|
||||||
|
{
|
||||||
|
if (m_poLen > 0U || m_buffer.getData() > 0U)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t CPOCSAGTX::writeData(const uint8_t* data, uint8_t length)
|
||||||
|
{
|
||||||
|
if (length != POCSAG_FRAME_LENGTH_BYTES)
|
||||||
|
return 4U;
|
||||||
|
|
||||||
|
uint16_t space = m_buffer.getSpace();
|
||||||
|
if (space < POCSAG_FRAME_LENGTH_BYTES)
|
||||||
|
return 5U;
|
||||||
|
|
||||||
|
for (uint8_t i = 0U; i < POCSAG_FRAME_LENGTH_BYTES; i++)
|
||||||
|
m_buffer.put(data[i]);
|
||||||
|
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPOCSAGTX::writeByte(uint8_t c)
|
||||||
|
{
|
||||||
|
q15_t inBuffer[POCSAG_RADIO_SYMBOL_LENGTH * 8U];
|
||||||
|
q15_t outBuffer[POCSAG_RADIO_SYMBOL_LENGTH * 8U];
|
||||||
|
|
||||||
|
const uint8_t MASK = 0x80U;
|
||||||
|
|
||||||
|
uint8_t n = 0U;
|
||||||
|
for (uint8_t i = 0U; i < 8U; i++, c <<= 1, n += POCSAG_RADIO_SYMBOL_LENGTH) {
|
||||||
|
switch (c & MASK) {
|
||||||
|
case 0x80U:
|
||||||
|
::memcpy(inBuffer + n, POCSAG_LEVEL1, POCSAG_RADIO_SYMBOL_LENGTH * sizeof(q15_t));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
::memcpy(inBuffer + n, POCSAG_LEVEL0, POCSAG_RADIO_SYMBOL_LENGTH * sizeof(q15_t));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::arm_fir_fast_q15(&m_modFilter, inBuffer, outBuffer, POCSAG_RADIO_SYMBOL_LENGTH * 8U);
|
||||||
|
|
||||||
|
io.write(STATE_POCSAG, outBuffer, POCSAG_RADIO_SYMBOL_LENGTH * 8U);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPOCSAGTX::setTXDelay(uint8_t delay)
|
||||||
|
{
|
||||||
|
m_txDelay = POCSAG_PREAMBLE_LENGTH_BYTES + (delay * 3U) / 2U;
|
||||||
|
|
||||||
|
if (m_txDelay > 150U)
|
||||||
|
m_txDelay = 150U;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t CPOCSAGTX::getSpace() const
|
||||||
|
{
|
||||||
|
return m_buffer.getSpace() / POCSAG_FRAME_LENGTH_BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
|
||||||
|
*
|
||||||
|
* 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(POCSAGTX_H)
|
||||||
|
#define POCSAGTX_H
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
|
#include "SerialRB.h"
|
||||||
|
|
||||||
|
class CPOCSAGTX {
|
||||||
|
public:
|
||||||
|
CPOCSAGTX();
|
||||||
|
|
||||||
|
uint8_t writeData(const uint8_t* data, uint8_t length);
|
||||||
|
|
||||||
|
void process();
|
||||||
|
|
||||||
|
void setTXDelay(uint8_t delay);
|
||||||
|
|
||||||
|
uint8_t getSpace() const;
|
||||||
|
|
||||||
|
bool busy();
|
||||||
|
|
||||||
|
private:
|
||||||
|
CSerialRB m_buffer;
|
||||||
|
arm_fir_instance_q15 m_modFilter;
|
||||||
|
q15_t m_modState[180U]; // NoTaps + BlockSize - 1, 12 + 160 - 1 plus some spare
|
||||||
|
uint8_t m_poBuffer[200U];
|
||||||
|
uint16_t m_poLen;
|
||||||
|
uint16_t m_poPtr;
|
||||||
|
uint16_t m_txDelay;
|
||||||
|
|
||||||
|
void writeByte(uint8_t c);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
This is the source code of the MMDVM firmware that supports D-Star, DMR, System Fusion and P25.
|
This is the source code of the MMDVM firmware that supports D-Star, DMR, System Fusion, P25, NXDN, and POCSAG modes.
|
||||||
|
|
||||||
It runs on the Arduino Due and the ST-Micro STM32F4xx platforms. Support for the Teensy (3.1/3.2 and 3.5/3.6) is being added.
|
It runs on the Arduino Due, the ST-Micro STM32F1xxx, STM32F4xxx and STM32F7xxx processors, as well as the Teensy 3.1/3.2/3.5/3.6. What these platforms have in common is the use of an ARM Cortex-M3 or M4 processor with a clock speed greater than 70 MHz, and access to at least one analogue to digital converter and one digital to analogue converter.
|
||||||
|
|
||||||
In order to build this software for the Arduino Due, you will need to edit a file within the Arduino GUI and that is detailed in the BUILD.txt file. The STM32 support is being supplied via the Coocox IDE with ARM GCC. The Teensy support is via the latest beta of Teensyduino.
|
In order to build this software for the Arduino Due, you will need to edit a file within the Arduino GUI and that is detailed in the BUILD.txt file. The STM32 support is being supplied via the Coocox IDE with ARM GCC. The Teensy support uses Teensyduino.
|
||||||
|
|
||||||
This software is licenced under the GPL v2 and is intended for amateur and educational use only. Use of this software for commercial purposes is strictly forbidden.
|
This software is licenced under the GPL v2 and is intended for amateur and educational use only. Use of this software for commercial purposes is strictly forbidden.
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ Boston, MA 02110-1301, USA.
|
|||||||
|
|
||||||
CRSSIRB::CRSSIRB(uint16_t length) :
|
CRSSIRB::CRSSIRB(uint16_t length) :
|
||||||
m_length(length),
|
m_length(length),
|
||||||
m_rssi(NULL),
|
|
||||||
m_head(0U),
|
m_head(0U),
|
||||||
m_tail(0U),
|
m_tail(0U),
|
||||||
m_full(false),
|
m_full(false),
|
||||||
@@ -101,4 +100,3 @@ bool CRSSIRB::hasOverflowed()
|
|||||||
|
|
||||||
return overflow;
|
return overflow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,12 @@ Boston, MA 02110-1301, USA.
|
|||||||
#if !defined(RSSIRB_H)
|
#if !defined(RSSIRB_H)
|
||||||
#define RSSIRB_H
|
#define RSSIRB_H
|
||||||
|
|
||||||
#if defined(STM32F4XX) || defined(STM32F4)
|
#if defined(STM32F4XX)
|
||||||
#include "stm32f4xx.h"
|
#include "stm32f4xx.h"
|
||||||
|
#elif defined(STM32F7XX)
|
||||||
|
#include "stm32f7xx.h"
|
||||||
|
#elif defined(STM32F105xC)
|
||||||
|
#include "stm32f1xx.h"
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#else
|
#else
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|||||||
+47
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Wojciech Krutnik N0CALL
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*
|
||||||
|
* FIFO ring buffer
|
||||||
|
* source:
|
||||||
|
* http://stackoverflow.com/questions/6822548/correct-way-of-implementing-a-uart-receive-buffer-in-a-small-arm-microcontroller
|
||||||
|
* (modified)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(RINGBUFF_H)
|
||||||
|
#define RINGBUFF_H
|
||||||
|
|
||||||
|
#define RINGBUFF_SIZE(ringBuff) (ringBuff.size) /* serial buffer in bytes (power 2) */
|
||||||
|
#define RINGBUFF_MASK(ringBuff) (ringBuff.size-1U) /* buffer size mask */
|
||||||
|
|
||||||
|
/* Buffer read / write macros */
|
||||||
|
#define RINGBUFF_RESET(ringBuff) (ringBuff).rdIdx = ringBuff.wrIdx = 0
|
||||||
|
#define RINGBUFF_WRITE(ringBuff, dataIn) (ringBuff).data[RINGBUFF_MASK(ringBuff) & ringBuff.wrIdx++] = (dataIn)
|
||||||
|
#define RINGBUFF_READ(ringBuff) ((ringBuff).data[RINGBUFF_MASK(ringBuff) & ((ringBuff).rdIdx++)])
|
||||||
|
#define RINGBUFF_EMPTY(ringBuff) ((ringBuff).rdIdx == (ringBuff).wrIdx)
|
||||||
|
#define RINGBUFF_FULL(ringBuff) ((RINGBUFF_MASK(ringBuff) & ringFifo.rdIdx) == (RINGBUFF_MASK(ringBuff) & ringFifo.wrIdx))
|
||||||
|
#define RINGBUFF_COUNT(ringBuff) (RINGBUFF_MASK(ringBuff) & ((ringBuff).wrIdx - (ringBuff).rdIdx))
|
||||||
|
|
||||||
|
/* Buffer type */
|
||||||
|
#define DECLARE_RINGBUFFER_TYPE(name, _size) \
|
||||||
|
typedef struct{ \
|
||||||
|
uint32_t size; \
|
||||||
|
uint32_t wrIdx; \
|
||||||
|
uint32_t rdIdx; \
|
||||||
|
uint8_t data[_size]; \
|
||||||
|
}name##_t
|
||||||
|
|
||||||
|
#endif
|
||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,664 @@
|
|||||||
|
/**************************************************************************//**
|
||||||
|
* @file core_cmFunc.h
|
||||||
|
* @brief CMSIS Cortex-M Core Function Access Header File
|
||||||
|
* @version V4.10
|
||||||
|
* @date 18. March 2015
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
/* Copyright (c) 2009 - 2015 ARM LIMITED
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
to endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
*
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __CORE_CMFUNC_H
|
||||||
|
#define __CORE_CMFUNC_H
|
||||||
|
|
||||||
|
|
||||||
|
/* ########################### Core Function Access ########################### */
|
||||||
|
/** \ingroup CMSIS_Core_FunctionInterface
|
||||||
|
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
|
||||||
|
/* ARM armcc specific functions */
|
||||||
|
|
||||||
|
#if (__ARMCC_VERSION < 400677)
|
||||||
|
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* intrinsic void __enable_irq(); */
|
||||||
|
/* intrinsic void __disable_irq(); */
|
||||||
|
|
||||||
|
/** \brief Get Control Register
|
||||||
|
|
||||||
|
This function returns the content of the Control Register.
|
||||||
|
|
||||||
|
\return Control Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_CONTROL(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regControl __ASM("control");
|
||||||
|
return(__regControl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Control Register
|
||||||
|
|
||||||
|
This function writes the given value to the Control Register.
|
||||||
|
|
||||||
|
\param [in] control Control Register value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_CONTROL(uint32_t control)
|
||||||
|
{
|
||||||
|
register uint32_t __regControl __ASM("control");
|
||||||
|
__regControl = control;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get IPSR Register
|
||||||
|
|
||||||
|
This function returns the content of the IPSR Register.
|
||||||
|
|
||||||
|
\return IPSR Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_IPSR(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regIPSR __ASM("ipsr");
|
||||||
|
return(__regIPSR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get APSR Register
|
||||||
|
|
||||||
|
This function returns the content of the APSR Register.
|
||||||
|
|
||||||
|
\return APSR Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_APSR(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regAPSR __ASM("apsr");
|
||||||
|
return(__regAPSR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get xPSR Register
|
||||||
|
|
||||||
|
This function returns the content of the xPSR Register.
|
||||||
|
|
||||||
|
\return xPSR Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_xPSR(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regXPSR __ASM("xpsr");
|
||||||
|
return(__regXPSR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Process Stack Pointer
|
||||||
|
|
||||||
|
This function returns the current value of the Process Stack Pointer (PSP).
|
||||||
|
|
||||||
|
\return PSP Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_PSP(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||||
|
return(__regProcessStackPointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Process Stack Pointer
|
||||||
|
|
||||||
|
This function assigns the given value to the Process Stack Pointer (PSP).
|
||||||
|
|
||||||
|
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
|
||||||
|
{
|
||||||
|
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||||
|
__regProcessStackPointer = topOfProcStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Main Stack Pointer
|
||||||
|
|
||||||
|
This function returns the current value of the Main Stack Pointer (MSP).
|
||||||
|
|
||||||
|
\return MSP Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_MSP(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regMainStackPointer __ASM("msp");
|
||||||
|
return(__regMainStackPointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Main Stack Pointer
|
||||||
|
|
||||||
|
This function assigns the given value to the Main Stack Pointer (MSP).
|
||||||
|
|
||||||
|
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
|
||||||
|
{
|
||||||
|
register uint32_t __regMainStackPointer __ASM("msp");
|
||||||
|
__regMainStackPointer = topOfMainStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Priority Mask
|
||||||
|
|
||||||
|
This function returns the current state of the priority mask bit from the Priority Mask Register.
|
||||||
|
|
||||||
|
\return Priority Mask value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_PRIMASK(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regPriMask __ASM("primask");
|
||||||
|
return(__regPriMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Priority Mask
|
||||||
|
|
||||||
|
This function assigns the given value to the Priority Mask Register.
|
||||||
|
|
||||||
|
\param [in] priMask Priority Mask
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
|
||||||
|
{
|
||||||
|
register uint32_t __regPriMask __ASM("primask");
|
||||||
|
__regPriMask = (priMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
|
||||||
|
|
||||||
|
/** \brief Enable FIQ
|
||||||
|
|
||||||
|
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
#define __enable_fault_irq __enable_fiq
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Disable FIQ
|
||||||
|
|
||||||
|
This function disables FIQ interrupts by setting the F-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
#define __disable_fault_irq __disable_fiq
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Base Priority
|
||||||
|
|
||||||
|
This function returns the current value of the Base Priority register.
|
||||||
|
|
||||||
|
\return Base Priority register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_BASEPRI(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regBasePri __ASM("basepri");
|
||||||
|
return(__regBasePri);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Base Priority
|
||||||
|
|
||||||
|
This function assigns the given value to the Base Priority register.
|
||||||
|
|
||||||
|
\param [in] basePri Base Priority value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
|
||||||
|
{
|
||||||
|
register uint32_t __regBasePri __ASM("basepri");
|
||||||
|
__regBasePri = (basePri & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Base Priority with condition
|
||||||
|
|
||||||
|
This function assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
|
||||||
|
or the new value increases the BASEPRI priority level.
|
||||||
|
|
||||||
|
\param [in] basePri Base Priority value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
|
||||||
|
{
|
||||||
|
register uint32_t __regBasePriMax __ASM("basepri_max");
|
||||||
|
__regBasePriMax = (basePri & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Fault Mask
|
||||||
|
|
||||||
|
This function returns the current value of the Fault Mask register.
|
||||||
|
|
||||||
|
\return Fault Mask register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regFaultMask __ASM("faultmask");
|
||||||
|
return(__regFaultMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Fault Mask
|
||||||
|
|
||||||
|
This function assigns the given value to the Fault Mask register.
|
||||||
|
|
||||||
|
\param [in] faultMask Fault Mask value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
|
||||||
|
{
|
||||||
|
register uint32_t __regFaultMask __ASM("faultmask");
|
||||||
|
__regFaultMask = (faultMask & (uint32_t)1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
|
||||||
|
|
||||||
|
|
||||||
|
#if (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07)
|
||||||
|
|
||||||
|
/** \brief Get FPSCR
|
||||||
|
|
||||||
|
This function returns the current value of the Floating Point Status/Control register.
|
||||||
|
|
||||||
|
\return Floating Point Status/Control register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_FPSCR(void)
|
||||||
|
{
|
||||||
|
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||||
|
register uint32_t __regfpscr __ASM("fpscr");
|
||||||
|
return(__regfpscr);
|
||||||
|
#else
|
||||||
|
return(0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set FPSCR
|
||||||
|
|
||||||
|
This function assigns the given value to the Floating Point Status/Control register.
|
||||||
|
|
||||||
|
\param [in] fpscr Floating Point Status/Control value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
||||||
|
{
|
||||||
|
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||||
|
register uint32_t __regfpscr __ASM("fpscr");
|
||||||
|
__regfpscr = (fpscr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
|
||||||
|
/* GNU gcc specific functions */
|
||||||
|
|
||||||
|
/** \brief Enable IRQ Interrupts
|
||||||
|
|
||||||
|
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("cpsie i" : : : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Disable IRQ Interrupts
|
||||||
|
|
||||||
|
This function disables IRQ interrupts by setting the I-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("cpsid i" : : : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Control Register
|
||||||
|
|
||||||
|
This function returns the content of the Control Register.
|
||||||
|
|
||||||
|
\return Control Register value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, control" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Control Register
|
||||||
|
|
||||||
|
This function writes the given value to the Control Register.
|
||||||
|
|
||||||
|
\param [in] control Control Register value to set
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get IPSR Register
|
||||||
|
|
||||||
|
This function returns the content of the IPSR Register.
|
||||||
|
|
||||||
|
\return IPSR Register value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get APSR Register
|
||||||
|
|
||||||
|
This function returns the content of the APSR Register.
|
||||||
|
|
||||||
|
\return APSR Register value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, apsr" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get xPSR Register
|
||||||
|
|
||||||
|
This function returns the content of the xPSR Register.
|
||||||
|
|
||||||
|
\return xPSR Register value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, xpsr" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Process Stack Pointer
|
||||||
|
|
||||||
|
This function returns the current value of the Process Stack Pointer (PSP).
|
||||||
|
|
||||||
|
\return PSP Register value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
|
||||||
|
{
|
||||||
|
register uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, psp\n" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Process Stack Pointer
|
||||||
|
|
||||||
|
This function assigns the given value to the Process Stack Pointer (PSP).
|
||||||
|
|
||||||
|
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Main Stack Pointer
|
||||||
|
|
||||||
|
This function returns the current value of the Main Stack Pointer (MSP).
|
||||||
|
|
||||||
|
\return MSP Register value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
|
||||||
|
{
|
||||||
|
register uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, msp\n" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Main Stack Pointer
|
||||||
|
|
||||||
|
This function assigns the given value to the Main Stack Pointer (MSP).
|
||||||
|
|
||||||
|
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Priority Mask
|
||||||
|
|
||||||
|
This function returns the current state of the priority mask bit from the Priority Mask Register.
|
||||||
|
|
||||||
|
\return Priority Mask value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, primask" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Priority Mask
|
||||||
|
|
||||||
|
This function assigns the given value to the Priority Mask Register.
|
||||||
|
|
||||||
|
\param [in] priMask Priority Mask
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (__CORTEX_M >= 0x03)
|
||||||
|
|
||||||
|
/** \brief Enable FIQ
|
||||||
|
|
||||||
|
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("cpsie f" : : : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Disable FIQ
|
||||||
|
|
||||||
|
This function disables FIQ interrupts by setting the F-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("cpsid f" : : : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Base Priority
|
||||||
|
|
||||||
|
This function returns the current value of the Base Priority register.
|
||||||
|
|
||||||
|
\return Base Priority register value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, basepri" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Base Priority
|
||||||
|
|
||||||
|
This function assigns the given value to the Base Priority register.
|
||||||
|
|
||||||
|
\param [in] basePri Base Priority value to set
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Base Priority with condition
|
||||||
|
|
||||||
|
This function assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
|
||||||
|
or the new value increases the BASEPRI priority level.
|
||||||
|
|
||||||
|
\param [in] basePri Base Priority value to set
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Fault Mask
|
||||||
|
|
||||||
|
This function returns the current value of the Fault Mask register.
|
||||||
|
|
||||||
|
\return Fault Mask register value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Fault Mask
|
||||||
|
|
||||||
|
This function assigns the given value to the Fault Mask register.
|
||||||
|
|
||||||
|
\param [in] faultMask Fault Mask value to set
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* (__CORTEX_M >= 0x03) */
|
||||||
|
|
||||||
|
|
||||||
|
#if (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07)
|
||||||
|
|
||||||
|
/** \brief Get FPSCR
|
||||||
|
|
||||||
|
This function returns the current value of the Floating Point Status/Control register.
|
||||||
|
|
||||||
|
\return Floating Point Status/Control register value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
|
||||||
|
{
|
||||||
|
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
/* Empty asm statement works as a scheduling barrier */
|
||||||
|
__ASM volatile ("");
|
||||||
|
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
|
||||||
|
__ASM volatile ("");
|
||||||
|
return(result);
|
||||||
|
#else
|
||||||
|
return(0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set FPSCR
|
||||||
|
|
||||||
|
This function assigns the given value to the Floating Point Status/Control register.
|
||||||
|
|
||||||
|
\param [in] fpscr Floating Point Status/Control value to set
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
||||||
|
{
|
||||||
|
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||||
|
/* Empty asm statement works as a scheduling barrier */
|
||||||
|
__ASM volatile ("");
|
||||||
|
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
|
||||||
|
__ASM volatile ("");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
|
||||||
|
/* IAR iccarm specific functions */
|
||||||
|
#include <cmsis_iar.h>
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
|
||||||
|
/* TI CCS specific functions */
|
||||||
|
#include <cmsis_ccs.h>
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
|
||||||
|
/* TASKING carm specific functions */
|
||||||
|
/*
|
||||||
|
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||||
|
* Please use "carm -?i" to get an up to date list of all intrinsics,
|
||||||
|
* Including the CMSIS ones.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
|
||||||
|
/* Cosmic specific functions */
|
||||||
|
#include <cmsis_csm.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*@} end of CMSIS_Core_RegAccFunctions */
|
||||||
|
|
||||||
|
#endif /* __CORE_CMFUNC_H */
|
||||||
@@ -0,0 +1,916 @@
|
|||||||
|
/**************************************************************************//**
|
||||||
|
* @file core_cmInstr.h
|
||||||
|
* @brief CMSIS Cortex-M Core Instruction Access Header File
|
||||||
|
* @version V4.10
|
||||||
|
* @date 18. March 2015
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
/* Copyright (c) 2009 - 2014 ARM LIMITED
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
to endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
*
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __CORE_CMINSTR_H
|
||||||
|
#define __CORE_CMINSTR_H
|
||||||
|
|
||||||
|
|
||||||
|
/* ########################## Core Instruction Access ######################### */
|
||||||
|
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
|
||||||
|
Access to dedicated instructions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
|
||||||
|
/* ARM armcc specific functions */
|
||||||
|
|
||||||
|
#if (__ARMCC_VERSION < 400677)
|
||||||
|
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief No Operation
|
||||||
|
|
||||||
|
No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||||
|
*/
|
||||||
|
#define __NOP __nop
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Wait For Interrupt
|
||||||
|
|
||||||
|
Wait For Interrupt is a hint instruction that suspends execution
|
||||||
|
until one of a number of events occurs.
|
||||||
|
*/
|
||||||
|
#define __WFI __wfi
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Wait For Event
|
||||||
|
|
||||||
|
Wait For Event is a hint instruction that permits the processor to enter
|
||||||
|
a low-power state until one of a number of events occurs.
|
||||||
|
*/
|
||||||
|
#define __WFE __wfe
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Send Event
|
||||||
|
|
||||||
|
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||||
|
*/
|
||||||
|
#define __SEV __sev
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Instruction Synchronization Barrier
|
||||||
|
|
||||||
|
Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||||
|
so that all instructions following the ISB are fetched from cache or
|
||||||
|
memory, after the instruction has been completed.
|
||||||
|
*/
|
||||||
|
#define __ISB() do {\
|
||||||
|
__schedule_barrier();\
|
||||||
|
__isb(0xF);\
|
||||||
|
__schedule_barrier();\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/** \brief Data Synchronization Barrier
|
||||||
|
|
||||||
|
This function acts as a special kind of Data Memory Barrier.
|
||||||
|
It completes when all explicit memory accesses before this instruction complete.
|
||||||
|
*/
|
||||||
|
#define __DSB() do {\
|
||||||
|
__schedule_barrier();\
|
||||||
|
__dsb(0xF);\
|
||||||
|
__schedule_barrier();\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/** \brief Data Memory Barrier
|
||||||
|
|
||||||
|
This function ensures the apparent order of the explicit memory operations before
|
||||||
|
and after the instruction, without ensuring their completion.
|
||||||
|
*/
|
||||||
|
#define __DMB() do {\
|
||||||
|
__schedule_barrier();\
|
||||||
|
__dmb(0xF);\
|
||||||
|
__schedule_barrier();\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/** \brief Reverse byte order (32 bit)
|
||||||
|
|
||||||
|
This function reverses the byte order in integer value.
|
||||||
|
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
#define __REV __rev
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Reverse byte order (16 bit)
|
||||||
|
|
||||||
|
This function reverses the byte order in two unsigned short values.
|
||||||
|
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
#ifndef __NO_EMBEDDED_ASM
|
||||||
|
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
|
||||||
|
{
|
||||||
|
rev16 r0, r0
|
||||||
|
bx lr
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** \brief Reverse byte order in signed short value
|
||||||
|
|
||||||
|
This function reverses the byte order in a signed short value with sign extension to integer.
|
||||||
|
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
#ifndef __NO_EMBEDDED_ASM
|
||||||
|
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
|
||||||
|
{
|
||||||
|
revsh r0, r0
|
||||||
|
bx lr
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Rotate Right in unsigned value (32 bit)
|
||||||
|
|
||||||
|
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||||
|
|
||||||
|
\param [in] value Value to rotate
|
||||||
|
\param [in] value Number of Bits to rotate
|
||||||
|
\return Rotated value
|
||||||
|
*/
|
||||||
|
#define __ROR __ror
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Breakpoint
|
||||||
|
|
||||||
|
This function causes the processor to enter Debug state.
|
||||||
|
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
|
||||||
|
|
||||||
|
\param [in] value is ignored by the processor.
|
||||||
|
If required, a debugger can use it to store additional information about the breakpoint.
|
||||||
|
*/
|
||||||
|
#define __BKPT(value) __breakpoint(value)
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Reverse bit order of value
|
||||||
|
|
||||||
|
This function reverses the bit order of the given value.
|
||||||
|
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
|
||||||
|
#define __RBIT __rbit
|
||||||
|
#else
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
int32_t s = 4 /*sizeof(v)*/ * 8 - 1; // extra shift needed at end
|
||||||
|
|
||||||
|
result = value; // r will be reversed bits of v; first get LSB of v
|
||||||
|
for (value >>= 1; value; value >>= 1)
|
||||||
|
{
|
||||||
|
result <<= 1;
|
||||||
|
result |= value & 1;
|
||||||
|
s--;
|
||||||
|
}
|
||||||
|
result <<= s; // shift when v's highest bits are zero
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Count leading zeros
|
||||||
|
|
||||||
|
This function counts the number of leading zeros of a data value.
|
||||||
|
|
||||||
|
\param [in] value Value to count the leading zeros
|
||||||
|
\return number of leading zeros in value
|
||||||
|
*/
|
||||||
|
#define __CLZ __clz
|
||||||
|
|
||||||
|
|
||||||
|
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
|
||||||
|
|
||||||
|
/** \brief LDR Exclusive (8 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive LDR instruction for 8 bit value.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint8_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief LDR Exclusive (16 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive LDR instruction for 16 bit values.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint16_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief LDR Exclusive (32 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive LDR instruction for 32 bit values.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint32_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STR Exclusive (8 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive STR instruction for 8 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
#define __STREXB(value, ptr) __strex(value, ptr)
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STR Exclusive (16 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive STR instruction for 16 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
#define __STREXH(value, ptr) __strex(value, ptr)
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STR Exclusive (32 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive STR instruction for 32 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
#define __STREXW(value, ptr) __strex(value, ptr)
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Remove the exclusive lock
|
||||||
|
|
||||||
|
This function removes the exclusive lock which is created by LDREX.
|
||||||
|
|
||||||
|
*/
|
||||||
|
#define __CLREX __clrex
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Signed Saturate
|
||||||
|
|
||||||
|
This function saturates a signed value.
|
||||||
|
|
||||||
|
\param [in] value Value to be saturated
|
||||||
|
\param [in] sat Bit position to saturate to (1..32)
|
||||||
|
\return Saturated value
|
||||||
|
*/
|
||||||
|
#define __SSAT __ssat
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Unsigned Saturate
|
||||||
|
|
||||||
|
This function saturates an unsigned value.
|
||||||
|
|
||||||
|
\param [in] value Value to be saturated
|
||||||
|
\param [in] sat Bit position to saturate to (0..31)
|
||||||
|
\return Saturated value
|
||||||
|
*/
|
||||||
|
#define __USAT __usat
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Rotate Right with Extend (32 bit)
|
||||||
|
|
||||||
|
This function moves each bit of a bitstring right by one bit.
|
||||||
|
The carry input is shifted in at the left end of the bitstring.
|
||||||
|
|
||||||
|
\param [in] value Value to rotate
|
||||||
|
\return Rotated value
|
||||||
|
*/
|
||||||
|
#ifndef __NO_EMBEDDED_ASM
|
||||||
|
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
|
||||||
|
{
|
||||||
|
rrx r0, r0
|
||||||
|
bx lr
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief LDRT Unprivileged (8 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged LDRT instruction for 8 bit value.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint8_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief LDRT Unprivileged (16 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged LDRT instruction for 16 bit values.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint16_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief LDRT Unprivileged (32 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged LDRT instruction for 32 bit values.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint32_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STRT Unprivileged (8 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged STRT instruction for 8 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
#define __STRBT(value, ptr) __strt(value, ptr)
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STRT Unprivileged (16 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged STRT instruction for 16 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
#define __STRHT(value, ptr) __strt(value, ptr)
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STRT Unprivileged (32 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged STRT instruction for 32 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
#define __STRT(value, ptr) __strt(value, ptr)
|
||||||
|
|
||||||
|
#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
|
||||||
|
/* GNU gcc specific functions */
|
||||||
|
|
||||||
|
/* Define macros for porting to both thumb1 and thumb2.
|
||||||
|
* For thumb1, use low register (r0-r7), specified by constrant "l"
|
||||||
|
* Otherwise, use general registers, specified by constrant "r" */
|
||||||
|
#if defined (__thumb__) && !defined (__thumb2__)
|
||||||
|
#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
|
||||||
|
#define __CMSIS_GCC_USE_REG(r) "l" (r)
|
||||||
|
#else
|
||||||
|
#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
|
||||||
|
#define __CMSIS_GCC_USE_REG(r) "r" (r)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** \brief No Operation
|
||||||
|
|
||||||
|
No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE void __NOP(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("nop");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Wait For Interrupt
|
||||||
|
|
||||||
|
Wait For Interrupt is a hint instruction that suspends execution
|
||||||
|
until one of a number of events occurs.
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE void __WFI(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("wfi");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Wait For Event
|
||||||
|
|
||||||
|
Wait For Event is a hint instruction that permits the processor to enter
|
||||||
|
a low-power state until one of a number of events occurs.
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE void __WFE(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("wfe");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Send Event
|
||||||
|
|
||||||
|
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE void __SEV(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("sev");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Instruction Synchronization Barrier
|
||||||
|
|
||||||
|
Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||||
|
so that all instructions following the ISB are fetched from cache or
|
||||||
|
memory, after the instruction has been completed.
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE void __ISB(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("isb 0xF":::"memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Data Synchronization Barrier
|
||||||
|
|
||||||
|
This function acts as a special kind of Data Memory Barrier.
|
||||||
|
It completes when all explicit memory accesses before this instruction complete.
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE void __DSB(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("dsb 0xF":::"memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Data Memory Barrier
|
||||||
|
|
||||||
|
This function ensures the apparent order of the explicit memory operations before
|
||||||
|
and after the instruction, without ensuring their completion.
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE void __DMB(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("dmb 0xF":::"memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Reverse byte order (32 bit)
|
||||||
|
|
||||||
|
This function reverses the byte order in integer value.
|
||||||
|
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value)
|
||||||
|
{
|
||||||
|
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
|
||||||
|
return __builtin_bswap32(value);
|
||||||
|
#else
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||||
|
return(result);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Reverse byte order (16 bit)
|
||||||
|
|
||||||
|
This function reverses the byte order in two unsigned short values.
|
||||||
|
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Reverse byte order in signed short value
|
||||||
|
|
||||||
|
This function reverses the byte order in a signed short value with sign extension to integer.
|
||||||
|
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value)
|
||||||
|
{
|
||||||
|
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||||
|
return (short)__builtin_bswap16(value);
|
||||||
|
#else
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||||
|
return(result);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Rotate Right in unsigned value (32 bit)
|
||||||
|
|
||||||
|
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||||
|
|
||||||
|
\param [in] value Value to rotate
|
||||||
|
\param [in] value Number of Bits to rotate
|
||||||
|
\return Rotated value
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
return (op1 >> op2) | (op1 << (32 - op2));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Breakpoint
|
||||||
|
|
||||||
|
This function causes the processor to enter Debug state.
|
||||||
|
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
|
||||||
|
|
||||||
|
\param [in] value is ignored by the processor.
|
||||||
|
If required, a debugger can use it to store additional information about the breakpoint.
|
||||||
|
*/
|
||||||
|
#define __BKPT(value) __ASM volatile ("bkpt "#value)
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Reverse bit order of value
|
||||||
|
|
||||||
|
This function reverses the bit order of the given value.
|
||||||
|
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
|
||||||
|
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
|
||||||
|
#else
|
||||||
|
int32_t s = 4 /*sizeof(v)*/ * 8 - 1; // extra shift needed at end
|
||||||
|
|
||||||
|
result = value; // r will be reversed bits of v; first get LSB of v
|
||||||
|
for (value >>= 1; value; value >>= 1)
|
||||||
|
{
|
||||||
|
result <<= 1;
|
||||||
|
result |= value & 1;
|
||||||
|
s--;
|
||||||
|
}
|
||||||
|
result <<= s; // shift when v's highest bits are zero
|
||||||
|
#endif
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Count leading zeros
|
||||||
|
|
||||||
|
This function counts the number of leading zeros of a data value.
|
||||||
|
|
||||||
|
\param [in] value Value to count the leading zeros
|
||||||
|
\return number of leading zeros in value
|
||||||
|
*/
|
||||||
|
#define __CLZ __builtin_clz
|
||||||
|
|
||||||
|
|
||||||
|
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
|
||||||
|
|
||||||
|
/** \brief LDR Exclusive (8 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive LDR instruction for 8 bit value.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint8_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||||
|
__ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||||
|
#else
|
||||||
|
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||||
|
accepted by assembler. So has to use following less efficient pattern.
|
||||||
|
*/
|
||||||
|
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||||
|
#endif
|
||||||
|
return ((uint8_t) result); /* Add explicit type cast here */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief LDR Exclusive (16 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive LDR instruction for 16 bit values.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint16_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||||
|
__ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||||
|
#else
|
||||||
|
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||||
|
accepted by assembler. So has to use following less efficient pattern.
|
||||||
|
*/
|
||||||
|
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||||
|
#endif
|
||||||
|
return ((uint16_t) result); /* Add explicit type cast here */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief LDR Exclusive (32 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive LDR instruction for 32 bit values.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint32_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STR Exclusive (8 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive STR instruction for 8 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STR Exclusive (16 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive STR instruction for 16 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STR Exclusive (32 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive STR instruction for 32 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Remove the exclusive lock
|
||||||
|
|
||||||
|
This function removes the exclusive lock which is created by LDREX.
|
||||||
|
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE void __CLREX(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("clrex" ::: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Signed Saturate
|
||||||
|
|
||||||
|
This function saturates a signed value.
|
||||||
|
|
||||||
|
\param [in] value Value to be saturated
|
||||||
|
\param [in] sat Bit position to saturate to (1..32)
|
||||||
|
\return Saturated value
|
||||||
|
*/
|
||||||
|
#define __SSAT(ARG1,ARG2) \
|
||||||
|
({ \
|
||||||
|
uint32_t __RES, __ARG1 = (ARG1); \
|
||||||
|
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||||
|
__RES; \
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Unsigned Saturate
|
||||||
|
|
||||||
|
This function saturates an unsigned value.
|
||||||
|
|
||||||
|
\param [in] value Value to be saturated
|
||||||
|
\param [in] sat Bit position to saturate to (0..31)
|
||||||
|
\return Saturated value
|
||||||
|
*/
|
||||||
|
#define __USAT(ARG1,ARG2) \
|
||||||
|
({ \
|
||||||
|
uint32_t __RES, __ARG1 = (ARG1); \
|
||||||
|
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||||
|
__RES; \
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Rotate Right with Extend (32 bit)
|
||||||
|
|
||||||
|
This function moves each bit of a bitstring right by one bit.
|
||||||
|
The carry input is shifted in at the left end of the bitstring.
|
||||||
|
|
||||||
|
\param [in] value Value to rotate
|
||||||
|
\return Rotated value
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief LDRT Unprivileged (8 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged LDRT instruction for 8 bit value.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint8_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||||
|
__ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||||
|
#else
|
||||||
|
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||||
|
accepted by assembler. So has to use following less efficient pattern.
|
||||||
|
*/
|
||||||
|
__ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||||
|
#endif
|
||||||
|
return ((uint8_t) result); /* Add explicit type cast here */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief LDRT Unprivileged (16 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged LDRT instruction for 16 bit values.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint16_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||||
|
__ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||||
|
#else
|
||||||
|
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||||
|
accepted by assembler. So has to use following less efficient pattern.
|
||||||
|
*/
|
||||||
|
__ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||||
|
#endif
|
||||||
|
return ((uint16_t) result); /* Add explicit type cast here */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief LDRT Unprivileged (32 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged LDRT instruction for 32 bit values.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint32_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STRT Unprivileged (8 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged STRT instruction for 8 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr)
|
||||||
|
{
|
||||||
|
__ASM volatile ("strbt %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STRT Unprivileged (16 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged STRT instruction for 16 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr)
|
||||||
|
{
|
||||||
|
__ASM volatile ("strht %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STRT Unprivileged (32 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged STRT instruction for 32 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr)
|
||||||
|
{
|
||||||
|
__ASM volatile ("strt %1, %0" : "=Q" (*addr) : "r" (value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
|
||||||
|
/* IAR iccarm specific functions */
|
||||||
|
#include <cmsis_iar.h>
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
|
||||||
|
/* TI CCS specific functions */
|
||||||
|
#include <cmsis_ccs.h>
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
|
||||||
|
/* TASKING carm specific functions */
|
||||||
|
/*
|
||||||
|
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||||
|
* Please use "carm -?i" to get an up to date list of all intrinsics,
|
||||||
|
* Including the CMSIS ones.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
|
||||||
|
/* Cosmic specific functions */
|
||||||
|
#include <cmsis_csm.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
|
||||||
|
|
||||||
|
#endif /* __CORE_CMINSTR_H */
|
||||||
@@ -0,0 +1,697 @@
|
|||||||
|
/**************************************************************************//**
|
||||||
|
* @file core_cmSimd.h
|
||||||
|
* @brief CMSIS Cortex-M SIMD Header File
|
||||||
|
* @version V4.10
|
||||||
|
* @date 18. March 2015
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
/* Copyright (c) 2009 - 2014 ARM LIMITED
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
to endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
*
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#if defined ( __ICCARM__ )
|
||||||
|
#pragma system_include /* treat file as system include file for MISRA check */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __CORE_CMSIMD_H
|
||||||
|
#define __CORE_CMSIMD_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Hardware Abstraction Layer
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* ################### Compiler specific Intrinsics ########################### */
|
||||||
|
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
|
||||||
|
Access to dedicated SIMD instructions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
|
||||||
|
/* ARM armcc specific functions */
|
||||||
|
#define __SADD8 __sadd8
|
||||||
|
#define __QADD8 __qadd8
|
||||||
|
#define __SHADD8 __shadd8
|
||||||
|
#define __UADD8 __uadd8
|
||||||
|
#define __UQADD8 __uqadd8
|
||||||
|
#define __UHADD8 __uhadd8
|
||||||
|
#define __SSUB8 __ssub8
|
||||||
|
#define __QSUB8 __qsub8
|
||||||
|
#define __SHSUB8 __shsub8
|
||||||
|
#define __USUB8 __usub8
|
||||||
|
#define __UQSUB8 __uqsub8
|
||||||
|
#define __UHSUB8 __uhsub8
|
||||||
|
#define __SADD16 __sadd16
|
||||||
|
#define __QADD16 __qadd16
|
||||||
|
#define __SHADD16 __shadd16
|
||||||
|
#define __UADD16 __uadd16
|
||||||
|
#define __UQADD16 __uqadd16
|
||||||
|
#define __UHADD16 __uhadd16
|
||||||
|
#define __SSUB16 __ssub16
|
||||||
|
#define __QSUB16 __qsub16
|
||||||
|
#define __SHSUB16 __shsub16
|
||||||
|
#define __USUB16 __usub16
|
||||||
|
#define __UQSUB16 __uqsub16
|
||||||
|
#define __UHSUB16 __uhsub16
|
||||||
|
#define __SASX __sasx
|
||||||
|
#define __QASX __qasx
|
||||||
|
#define __SHASX __shasx
|
||||||
|
#define __UASX __uasx
|
||||||
|
#define __UQASX __uqasx
|
||||||
|
#define __UHASX __uhasx
|
||||||
|
#define __SSAX __ssax
|
||||||
|
#define __QSAX __qsax
|
||||||
|
#define __SHSAX __shsax
|
||||||
|
#define __USAX __usax
|
||||||
|
#define __UQSAX __uqsax
|
||||||
|
#define __UHSAX __uhsax
|
||||||
|
#define __USAD8 __usad8
|
||||||
|
#define __USADA8 __usada8
|
||||||
|
#define __SSAT16 __ssat16
|
||||||
|
#define __USAT16 __usat16
|
||||||
|
#define __UXTB16 __uxtb16
|
||||||
|
#define __UXTAB16 __uxtab16
|
||||||
|
#define __SXTB16 __sxtb16
|
||||||
|
#define __SXTAB16 __sxtab16
|
||||||
|
#define __SMUAD __smuad
|
||||||
|
#define __SMUADX __smuadx
|
||||||
|
#define __SMLAD __smlad
|
||||||
|
#define __SMLADX __smladx
|
||||||
|
#define __SMLALD __smlald
|
||||||
|
#define __SMLALDX __smlaldx
|
||||||
|
#define __SMUSD __smusd
|
||||||
|
#define __SMUSDX __smusdx
|
||||||
|
#define __SMLSD __smlsd
|
||||||
|
#define __SMLSDX __smlsdx
|
||||||
|
#define __SMLSLD __smlsld
|
||||||
|
#define __SMLSLDX __smlsldx
|
||||||
|
#define __SEL __sel
|
||||||
|
#define __QADD __qadd
|
||||||
|
#define __QSUB __qsub
|
||||||
|
|
||||||
|
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
|
||||||
|
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
|
||||||
|
|
||||||
|
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
|
||||||
|
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
|
||||||
|
|
||||||
|
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
|
||||||
|
((int64_t)(ARG3) << 32) ) >> 32))
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
|
||||||
|
/* GNU gcc specific functions */
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define __SSAT16(ARG1,ARG2) \
|
||||||
|
({ \
|
||||||
|
uint32_t __RES, __ARG1 = (ARG1); \
|
||||||
|
__ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||||
|
__RES; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define __USAT16(ARG1,ARG2) \
|
||||||
|
({ \
|
||||||
|
uint32_t __RES, __ARG1 = (ARG1); \
|
||||||
|
__ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||||
|
__RES; \
|
||||||
|
})
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc)
|
||||||
|
{
|
||||||
|
union llreg_u{
|
||||||
|
uint32_t w32[2];
|
||||||
|
uint64_t w64;
|
||||||
|
} llr;
|
||||||
|
llr.w64 = acc;
|
||||||
|
|
||||||
|
#ifndef __ARMEB__ // Little endian
|
||||||
|
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
|
||||||
|
#else // Big endian
|
||||||
|
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(llr.w64);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)
|
||||||
|
{
|
||||||
|
union llreg_u{
|
||||||
|
uint32_t w32[2];
|
||||||
|
uint64_t w64;
|
||||||
|
} llr;
|
||||||
|
llr.w64 = acc;
|
||||||
|
|
||||||
|
#ifndef __ARMEB__ // Little endian
|
||||||
|
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
|
||||||
|
#else // Big endian
|
||||||
|
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(llr.w64);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc)
|
||||||
|
{
|
||||||
|
union llreg_u{
|
||||||
|
uint32_t w32[2];
|
||||||
|
uint64_t w64;
|
||||||
|
} llr;
|
||||||
|
llr.w64 = acc;
|
||||||
|
|
||||||
|
#ifndef __ARMEB__ // Little endian
|
||||||
|
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
|
||||||
|
#else // Big endian
|
||||||
|
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(llr.w64);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc)
|
||||||
|
{
|
||||||
|
union llreg_u{
|
||||||
|
uint32_t w32[2];
|
||||||
|
uint64_t w64;
|
||||||
|
} llr;
|
||||||
|
llr.w64 = acc;
|
||||||
|
|
||||||
|
#ifndef __ARMEB__ // Little endian
|
||||||
|
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
|
||||||
|
#else // Big endian
|
||||||
|
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(llr.w64);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define __PKHBT(ARG1,ARG2,ARG3) \
|
||||||
|
({ \
|
||||||
|
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
|
||||||
|
__ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
|
||||||
|
__RES; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define __PKHTB(ARG1,ARG2,ARG3) \
|
||||||
|
({ \
|
||||||
|
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
|
||||||
|
if (ARG3 == 0) \
|
||||||
|
__ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
|
||||||
|
else \
|
||||||
|
__ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
|
||||||
|
__RES; \
|
||||||
|
})
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
|
||||||
|
{
|
||||||
|
int32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
|
||||||
|
/* IAR iccarm specific functions */
|
||||||
|
#include <cmsis_iar.h>
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
|
||||||
|
/* TI CCS specific functions */
|
||||||
|
#include <cmsis_ccs.h>
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
|
||||||
|
/* TASKING carm specific functions */
|
||||||
|
/* not yet supported */
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
|
||||||
|
/* Cosmic specific functions */
|
||||||
|
#include <cmsis_csm.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_SIMD_intrinsics */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __CORE_CMSIMD_H */
|
||||||
Binary file not shown.
@@ -0,0 +1,436 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file startup_stm32f4xx.s
|
||||||
|
* @author Coocox
|
||||||
|
* @version V1.0
|
||||||
|
* @date 03/05/2012
|
||||||
|
* @brief STM32F4xx Devices vector table for RIDE7 toolchain.
|
||||||
|
* This module performs:
|
||||||
|
* - Set the initial SP
|
||||||
|
* - Set the initial PC == Reset_Handler,
|
||||||
|
* - Set the vector table entries with the exceptions ISR address
|
||||||
|
* - Configure the clock system and the external SRAM mounted on
|
||||||
|
* STM324xG-EVAL board to be used as data memory (optional,
|
||||||
|
* to be enabled by user)
|
||||||
|
* - Branches to main in the C library (which eventually
|
||||||
|
* calls main()).
|
||||||
|
* After Reset the Cortex-M4 processor is in Thread mode,
|
||||||
|
* priority is Privileged, and the Stack is set to Main.
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Some modifications by Andy Uribe CA6JAU :
|
||||||
|
- Added C++ global constructors support
|
||||||
|
- Changed initial stack pointer
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*----------Macro definition--------------------------------------------------*/
|
||||||
|
#define WEAK __attribute__ ((weak))
|
||||||
|
|
||||||
|
/*----------Declaration of the default fault handlers-------------------------*/
|
||||||
|
/* System exception vector handler */
|
||||||
|
__attribute__ ((used))
|
||||||
|
void WEAK Reset_Handler(void);
|
||||||
|
void WEAK NMI_Handler(void);
|
||||||
|
void WEAK HardFault_Handler(void);
|
||||||
|
void WEAK MemManage_Handler(void);
|
||||||
|
void WEAK BusFault_Handler(void);
|
||||||
|
void WEAK UsageFault_Handler(void);
|
||||||
|
void WEAK SVC_Handler(void);
|
||||||
|
void WEAK DebugMon_Handler(void);
|
||||||
|
void WEAK PendSV_Handler(void);
|
||||||
|
void WEAK SysTick_Handler(void);
|
||||||
|
|
||||||
|
void WEAK WWDG_IRQHandler(void);
|
||||||
|
void WEAK PVD_IRQHandler(void);
|
||||||
|
void WEAK TAMP_STAMP_IRQHandler(void);
|
||||||
|
void WEAK RTC_WKUP_IRQHandler(void);
|
||||||
|
void WEAK FLASH_IRQHandler(void);
|
||||||
|
void WEAK RCC_IRQHandler(void);
|
||||||
|
void WEAK EXTI0_IRQHandler(void);
|
||||||
|
void WEAK EXTI1_IRQHandler(void);
|
||||||
|
void WEAK EXTI2_IRQHandler(void);
|
||||||
|
void WEAK EXTI3_IRQHandler(void);
|
||||||
|
void WEAK EXTI4_IRQHandler(void);
|
||||||
|
void WEAK DMA1_Stream0_IRQHandler(void);
|
||||||
|
void WEAK DMA1_Stream1_IRQHandler(void);
|
||||||
|
void WEAK DMA1_Stream2_IRQHandler(void);
|
||||||
|
void WEAK DMA1_Stream3_IRQHandler(void);
|
||||||
|
void WEAK DMA1_Stream4_IRQHandler(void);
|
||||||
|
void WEAK DMA1_Stream5_IRQHandler(void);
|
||||||
|
void WEAK DMA1_Stream6_IRQHandler(void);
|
||||||
|
void WEAK ADC_IRQHandler(void);
|
||||||
|
void WEAK CAN1_TX_IRQHandler(void);
|
||||||
|
void WEAK CAN1_RX0_IRQHandler(void);
|
||||||
|
void WEAK CAN1_RX1_IRQHandler(void);
|
||||||
|
void WEAK CAN1_SCE_IRQHandler(void);
|
||||||
|
void WEAK EXTI9_5_IRQHandler(void);
|
||||||
|
void WEAK TIM1_BRK_TIM9_IRQHandler(void);
|
||||||
|
void WEAK TIM1_UP_TIM10_IRQHandler(void);
|
||||||
|
void WEAK TIM1_TRG_COM_TIM11_IRQHandler(void);
|
||||||
|
void WEAK TIM1_CC_IRQHandler(void);
|
||||||
|
void WEAK TIM2_IRQHandler(void);
|
||||||
|
void WEAK TIM3_IRQHandler(void);
|
||||||
|
void WEAK TIM4_IRQHandler(void);
|
||||||
|
void WEAK I2C1_EV_IRQHandler(void);
|
||||||
|
void WEAK I2C1_ER_IRQHandler(void);
|
||||||
|
void WEAK I2C2_EV_IRQHandler(void);
|
||||||
|
void WEAK I2C2_ER_IRQHandler(void);
|
||||||
|
void WEAK SPI1_IRQHandler(void);
|
||||||
|
void WEAK SPI2_IRQHandler(void);
|
||||||
|
void WEAK USART1_IRQHandler(void);
|
||||||
|
void WEAK USART2_IRQHandler(void);
|
||||||
|
void WEAK USART3_IRQHandler(void);
|
||||||
|
void WEAK EXTI15_10_IRQHandler(void);
|
||||||
|
void WEAK RTC_Alarm_IRQHandler(void);
|
||||||
|
void WEAK OTG_FS_WKUP_IRQHandler(void);
|
||||||
|
void WEAK TIM8_BRK_TIM12_IRQHandler(void);
|
||||||
|
void WEAK TIM8_UP_TIM13_IRQHandler(void);
|
||||||
|
void WEAK TIM8_TRG_COM_TIM14_IRQHandler(void);
|
||||||
|
void WEAK TIM8_CC_IRQHandler(void);
|
||||||
|
void WEAK DMA1_Stream7_IRQHandler(void);
|
||||||
|
void WEAK FSMC_IRQHandler(void);
|
||||||
|
void WEAK SDIO_IRQHandler(void);
|
||||||
|
void WEAK TIM5_IRQHandler(void);
|
||||||
|
void WEAK SPI3_IRQHandler(void);
|
||||||
|
void WEAK UART4_IRQHandler(void);
|
||||||
|
void WEAK UART5_IRQHandler(void);
|
||||||
|
void WEAK TIM6_DAC_IRQHandler(void);
|
||||||
|
void WEAK TIM7_IRQHandler(void);
|
||||||
|
void WEAK DMA2_Stream0_IRQHandler(void);
|
||||||
|
void WEAK DMA2_Stream1_IRQHandler(void);
|
||||||
|
void WEAK DMA2_Stream2_IRQHandler(void);
|
||||||
|
void WEAK DMA2_Stream3_IRQHandler(void);
|
||||||
|
void WEAK DMA2_Stream4_IRQHandler(void);
|
||||||
|
void WEAK ETH_IRQHandler(void);
|
||||||
|
void WEAK ETH_WKUP_IRQHandler(void);
|
||||||
|
void WEAK CAN2_TX_IRQHandler(void);
|
||||||
|
void WEAK CAN2_RX0_IRQHandler(void);
|
||||||
|
void WEAK CAN2_RX1_IRQHandler(void);
|
||||||
|
void WEAK CAN2_SCE_IRQHandler(void);
|
||||||
|
void WEAK OTG_FS_IRQHandler(void);
|
||||||
|
void WEAK DMA2_Stream5_IRQHandler(void);
|
||||||
|
void WEAK DMA2_Stream6_IRQHandler(void);
|
||||||
|
void WEAK DMA2_Stream7_IRQHandler(void);
|
||||||
|
void WEAK USART6_IRQHandler(void);
|
||||||
|
void WEAK I2C3_EV_IRQHandler(void);
|
||||||
|
void WEAK I2C3_ER_IRQHandler(void);
|
||||||
|
void WEAK OTG_HS_EP1_OUT_IRQHandler(void);
|
||||||
|
void WEAK OTG_HS_EP1_IN_IRQHandler(void);
|
||||||
|
void WEAK OTG_HS_WKUP_IRQHandler(void);
|
||||||
|
void WEAK OTG_HS_IRQHandler(void);
|
||||||
|
void WEAK DCMI_IRQHandler(void);
|
||||||
|
void WEAK CRYP_IRQHandler(void);
|
||||||
|
void WEAK HASH_RNG_IRQHandler(void);
|
||||||
|
void WEAK FPU_IRQHandler(void);
|
||||||
|
|
||||||
|
/*----------Symbols defined in linker script----------------------------------*/
|
||||||
|
extern unsigned long _estack; /*!< The initial stack pointer */
|
||||||
|
extern unsigned long _sidata; /*!< Start address for the initialization
|
||||||
|
values of the .data section. */
|
||||||
|
extern unsigned long _sdata; /*!< Start address for the .data section */
|
||||||
|
extern unsigned long _edata; /*!< End address for the .data section */
|
||||||
|
extern unsigned long _sbss; /*!< Start address for the .bss section */
|
||||||
|
extern unsigned long _ebss; /*!< End address for the .bss section */
|
||||||
|
|
||||||
|
/* C++ global constructors support */
|
||||||
|
extern unsigned long __preinit_array_start;
|
||||||
|
extern unsigned long __preinit_array_end;
|
||||||
|
extern unsigned long __init_array_start;
|
||||||
|
extern unsigned long __init_array_end;
|
||||||
|
|
||||||
|
/*----------Function prototypes-----------------------------------------------*/
|
||||||
|
extern int main(void); /*!< The entry point for the application. */
|
||||||
|
//extern void SystemInit(void); /*!< Setup the microcontroller system(CMSIS) */
|
||||||
|
void Default_Reset_Handler(void); /*!< Default reset handler */
|
||||||
|
static void Default_Handler(void); /*!< Default exception handler */
|
||||||
|
static void call_constructors(unsigned long *start, unsigned long *end) __attribute((noinline));
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@brief The minimal vector table for a Cortex M3. Note that the proper constructs
|
||||||
|
* must be placed on this to ensure that it ends up at physical address
|
||||||
|
* 0x00000000.
|
||||||
|
*/
|
||||||
|
__attribute__ ((used,section(".isr_vector")))
|
||||||
|
void (* const g_pfnVectors[])(void) =
|
||||||
|
{
|
||||||
|
/*----------Core Exceptions------------------------------------------------ */
|
||||||
|
(void *) &_estack, /*!< The initial stack pointer */
|
||||||
|
Reset_Handler, /*!< Reset Handler */
|
||||||
|
NMI_Handler, /*!< NMI Handler */
|
||||||
|
HardFault_Handler, /*!< Hard Fault Handler */
|
||||||
|
MemManage_Handler, /*!< MPU Fault Handler */
|
||||||
|
BusFault_Handler, /*!< Bus Fault Handler */
|
||||||
|
UsageFault_Handler, /*!< Usage Fault Handler */
|
||||||
|
0,0,0,0, /*!< Reserved */
|
||||||
|
SVC_Handler, /*!< SVCall Handler */
|
||||||
|
DebugMon_Handler, /*!< Debug Monitor Handler */
|
||||||
|
0, /*!< Reserved */
|
||||||
|
PendSV_Handler, /*!< PendSV Handler */
|
||||||
|
SysTick_Handler, /*!< SysTick Handler */
|
||||||
|
|
||||||
|
/*----------External Exceptions---------------------------------------------*/
|
||||||
|
WWDG_IRQHandler, /*!< 0: Window WatchDog */
|
||||||
|
PVD_IRQHandler, /*!< 1: PVD through EXTI Line detection */
|
||||||
|
TAMP_STAMP_IRQHandler, /*!< 2: Tamper and TimeStamps through the EXTI line*/
|
||||||
|
RTC_WKUP_IRQHandler, /*!< 3: RTC Wakeup through the EXTI line */
|
||||||
|
FLASH_IRQHandler, /*!< 4: FLASH */
|
||||||
|
RCC_IRQHandler , /*!< 5: RCC */
|
||||||
|
EXTI0_IRQHandler, /*!< 6: EXTI Line0 */
|
||||||
|
EXTI1_IRQHandler, /*!< 7: EXTI Line1 */
|
||||||
|
EXTI2_IRQHandler, /*!< 8: EXTI Line2 */
|
||||||
|
EXTI3_IRQHandler, /*!< 9: EXTI Line3 */
|
||||||
|
EXTI4_IRQHandler, /*!< 10: EXTI Line4 */
|
||||||
|
DMA1_Stream0_IRQHandler, /*!< 11: DMA1 Stream 0 */
|
||||||
|
DMA1_Stream1_IRQHandler, /*!< 12: DMA1 Stream 1 */
|
||||||
|
DMA1_Stream2_IRQHandler, /*!< 13: DMA1 Stream 2 */
|
||||||
|
DMA1_Stream3_IRQHandler, /*!< 14: DMA1 Stream 3 */
|
||||||
|
DMA1_Stream4_IRQHandler, /*!< 15: DMA1 Stream 4 */
|
||||||
|
DMA1_Stream5_IRQHandler, /*!< 16: DMA1 Stream 5 */
|
||||||
|
DMA1_Stream6_IRQHandler, /*!< 17: DMA1 Stream 6 */
|
||||||
|
ADC_IRQHandler, /*!< 18: ADC1, ADC2 and ADC3s */
|
||||||
|
CAN1_TX_IRQHandler, /*!< 19: CAN1 TX */
|
||||||
|
CAN1_RX0_IRQHandler, /*!< 20: CAN1 RX0 */
|
||||||
|
CAN1_RX1_IRQHandler, /*!< 21: CAN1 RX1 */
|
||||||
|
CAN1_SCE_IRQHandler, /*!< 22: CAN1 SCE */
|
||||||
|
EXTI9_5_IRQHandler, /*!< 23: External Line[9:5]s */
|
||||||
|
TIM1_BRK_TIM9_IRQHandler, /*!< 24: TIM1 Break and TIM9 */
|
||||||
|
TIM1_UP_TIM10_IRQHandler, /*!< 25: TIM1 Update and TIM10 */
|
||||||
|
TIM1_TRG_COM_TIM11_IRQHandler,/*!< 26: TIM1 Trigger and Commutation and TIM11*/
|
||||||
|
TIM1_CC_IRQHandler, /*!< 27: TIM1 Capture Compare */
|
||||||
|
TIM2_IRQHandler, /*!< 28: TIM2 */
|
||||||
|
TIM3_IRQHandler, /*!< 29: TIM3 */
|
||||||
|
TIM4_IRQHandler, /*!< 30: TIM4 */
|
||||||
|
I2C1_EV_IRQHandler, /*!< 31: I2C1 Event */
|
||||||
|
I2C1_ER_IRQHandler, /*!< 32: I2C1 Error */
|
||||||
|
I2C2_EV_IRQHandler, /*!< 33: I2C2 Event */
|
||||||
|
I2C2_ER_IRQHandler, /*!< 34: I2C2 Error */
|
||||||
|
SPI1_IRQHandler, /*!< 35: SPI1 */
|
||||||
|
SPI2_IRQHandler, /*!< 36: SPI2 */
|
||||||
|
USART1_IRQHandler, /*!< 37: USART1 */
|
||||||
|
USART2_IRQHandler, /*!< 38: USART2 */
|
||||||
|
USART3_IRQHandler, /*!< 39: USART3 */
|
||||||
|
EXTI15_10_IRQHandler, /*!< 40: External Line[15:10]s */
|
||||||
|
RTC_Alarm_IRQHandler, /*!< 41: RTC Alarm (A and B) through EXTI Line */
|
||||||
|
OTG_FS_WKUP_IRQHandler, /*!< 42: USB OTG FS Wakeup through EXTI line */
|
||||||
|
TIM8_BRK_TIM12_IRQHandler, /*!< 43: TIM8 Break and TIM12 */
|
||||||
|
TIM8_UP_TIM13_IRQHandler, /*!< 44: TIM8 Update and TIM13 */
|
||||||
|
TIM8_TRG_COM_TIM14_IRQHandler,/*!< 45:TIM8 Trigger and Commutation and TIM14*/
|
||||||
|
TIM8_CC_IRQHandler, /*!< 46: TIM8 Capture Compare */
|
||||||
|
DMA1_Stream7_IRQHandler, /*!< 47: DMA1 Stream7 */
|
||||||
|
FSMC_IRQHandler, /*!< 48: FSMC */
|
||||||
|
SDIO_IRQHandler, /*!< 49: SDIO */
|
||||||
|
TIM5_IRQHandler, /*!< 50: TIM5 */
|
||||||
|
SPI3_IRQHandler, /*!< 51: SPI3 */
|
||||||
|
UART4_IRQHandler, /*!< 52: UART4 */
|
||||||
|
UART5_IRQHandler, /*!< 53: UART5 */
|
||||||
|
TIM6_DAC_IRQHandler, /*!< 54: TIM6 and DAC1&2 underrun errors */
|
||||||
|
TIM7_IRQHandler, /*!< 55: TIM7 */
|
||||||
|
DMA2_Stream0_IRQHandler, /*!< 56: DMA2 Stream 0 */
|
||||||
|
DMA2_Stream1_IRQHandler, /*!< 57: DMA2 Stream 1 */
|
||||||
|
DMA2_Stream2_IRQHandler, /*!< 58: DMA2 Stream 2 */
|
||||||
|
DMA2_Stream3_IRQHandler, /*!< 59: DMA2 Stream 3 */
|
||||||
|
DMA2_Stream4_IRQHandler, /*!< 60: DMA2 Stream 4 */
|
||||||
|
ETH_IRQHandler, /*!< 61: Ethernet */
|
||||||
|
ETH_WKUP_IRQHandler, /*!< 62: Ethernet Wakeup through EXTI line */
|
||||||
|
CAN2_TX_IRQHandler, /*!< 63: CAN2 TX */
|
||||||
|
CAN2_RX0_IRQHandler, /*!< 64: CAN2 RX0 */
|
||||||
|
CAN2_RX1_IRQHandler, /*!< 65: CAN2 RX1 */
|
||||||
|
CAN2_SCE_IRQHandler, /*!< 66: CAN2 SCE */
|
||||||
|
OTG_FS_IRQHandler, /*!< 67: USB OTG FS */
|
||||||
|
DMA2_Stream5_IRQHandler, /*!< 68: DMA2 Stream 5 */
|
||||||
|
DMA2_Stream6_IRQHandler, /*!< 69: DMA2 Stream 6 */
|
||||||
|
DMA2_Stream7_IRQHandler, /*!< 70: DMA2 Stream 7 */
|
||||||
|
USART6_IRQHandler, /*!< 71: USART6 */
|
||||||
|
I2C3_EV_IRQHandler, /*!< 72: I2C3 event */
|
||||||
|
I2C3_ER_IRQHandler, /*!< 73: I2C3 error */
|
||||||
|
OTG_HS_EP1_OUT_IRQHandler, /*!< 74: USB OTG HS End Point 1 Out */
|
||||||
|
OTG_HS_EP1_IN_IRQHandler, /*!< 75: USB OTG HS End Point 1 In */
|
||||||
|
OTG_HS_WKUP_IRQHandler, /*!< 76: USB OTG HS Wakeup through EXTI */
|
||||||
|
OTG_HS_IRQHandler, /*!< 77: USB OTG HS */
|
||||||
|
DCMI_IRQHandler, /*!< 53: DCMI */
|
||||||
|
CRYP_IRQHandler, /*!< 53: CRYP crypto */
|
||||||
|
HASH_RNG_IRQHandler, /*!< 53: Hash and Rng */
|
||||||
|
FPU_IRQHandler /*!< 53: FPU */
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/* C++ global constructors support */
|
||||||
|
static void call_constructors(unsigned long *start, unsigned long *end)
|
||||||
|
{
|
||||||
|
unsigned long *i;
|
||||||
|
void (*funcptr)();
|
||||||
|
for ( i = start; i < end; i++)
|
||||||
|
{
|
||||||
|
funcptr=(void (*)())(*i);
|
||||||
|
funcptr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This is the code that gets called when the processor first
|
||||||
|
* starts execution following a reset event. Only the absolutely
|
||||||
|
* necessary set is performed, after which the application
|
||||||
|
* supplied main() routine is called.
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void Default_Reset_Handler(void)
|
||||||
|
{
|
||||||
|
/* Initialize data and bss */
|
||||||
|
unsigned long *pulSrc, *pulDest;
|
||||||
|
|
||||||
|
/* Copy the data segment initializers from flash to SRAM */
|
||||||
|
pulSrc = &_sidata;
|
||||||
|
|
||||||
|
for(pulDest = &_sdata; pulDest < &_edata; )
|
||||||
|
{
|
||||||
|
*(pulDest++) = *(pulSrc++);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zero fill the bss segment. This is done with inline assembly since this
|
||||||
|
will clear the value of pulDest if it is not kept in a register. */
|
||||||
|
__asm(" ldr r0, =_sbss\n"
|
||||||
|
" ldr r1, =_ebss\n"
|
||||||
|
" mov r2, #0\n"
|
||||||
|
" .thumb_func\n"
|
||||||
|
"zero_loop:\n"
|
||||||
|
" cmp r0, r1\n"
|
||||||
|
" it lt\n"
|
||||||
|
" strlt r2, [r0], #4\n"
|
||||||
|
" blt zero_loop");
|
||||||
|
#ifdef __FPU_USED
|
||||||
|
/* Enable FPU.*/
|
||||||
|
__asm(" LDR.W R0, =0xE000ED88\n"
|
||||||
|
" LDR R1, [R0]\n"
|
||||||
|
" ORR R1, R1, #(0xF << 20)\n"
|
||||||
|
" STR R1, [R0]");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SystemInit();
|
||||||
|
|
||||||
|
//Call C++ global constructors
|
||||||
|
call_constructors(&__preinit_array_start, &__preinit_array_end);
|
||||||
|
call_constructors(&__init_array_start, &__init_array_end);
|
||||||
|
|
||||||
|
/* Call the application's entry point.*/
|
||||||
|
main();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@brief Provide weak aliases for each Exception handler to the Default_Handler.
|
||||||
|
* As they are weak aliases, any function with the same name will override
|
||||||
|
* this definition.
|
||||||
|
*/
|
||||||
|
#pragma weak Reset_Handler = Default_Reset_Handler
|
||||||
|
#pragma weak NMI_Handler = Default_Handler
|
||||||
|
#pragma weak HardFault_Handler = Default_Handler
|
||||||
|
#pragma weak MemManage_Handler = Default_Handler
|
||||||
|
#pragma weak BusFault_Handler = Default_Handler
|
||||||
|
#pragma weak UsageFault_Handler = Default_Handler
|
||||||
|
#pragma weak SVC_Handler = Default_Handler
|
||||||
|
#pragma weak DebugMon_Handler = Default_Handler
|
||||||
|
#pragma weak PendSV_Handler = Default_Handler
|
||||||
|
#pragma weak SysTick_Handler = Default_Handler
|
||||||
|
|
||||||
|
#pragma weak WWDG_IRQHandler = Default_Handler
|
||||||
|
#pragma weak PVD_IRQHandler = Default_Handler
|
||||||
|
#pragma weak TAMP_STAMP_IRQHandler = Default_Handler
|
||||||
|
#pragma weak RTC_WKUP_IRQHandler = Default_Handler
|
||||||
|
#pragma weak FLASH_IRQHandler = Default_Handler
|
||||||
|
#pragma weak RCC_IRQHandler = Default_Handler
|
||||||
|
#pragma weak EXTI0_IRQHandler = Default_Handler
|
||||||
|
#pragma weak EXTI1_IRQHandler = Default_Handler
|
||||||
|
#pragma weak EXTI2_IRQHandler = Default_Handler
|
||||||
|
#pragma weak EXTI3_IRQHandler = Default_Handler
|
||||||
|
#pragma weak EXTI4_IRQHandler = Default_Handler
|
||||||
|
#pragma weak DMA1_Stream0_IRQHandler = Default_Handler
|
||||||
|
#pragma weak DMA1_Stream1_IRQHandler = Default_Handler
|
||||||
|
#pragma weak DMA1_Stream2_IRQHandler = Default_Handler
|
||||||
|
#pragma weak DMA1_Stream3_IRQHandler = Default_Handler
|
||||||
|
#pragma weak DMA1_Stream4_IRQHandler = Default_Handler
|
||||||
|
#pragma weak DMA1_Stream5_IRQHandler = Default_Handler
|
||||||
|
#pragma weak DMA1_Stream6_IRQHandler = Default_Handler
|
||||||
|
#pragma weak ADC_IRQHandler = Default_Handler
|
||||||
|
#pragma weak CAN1_TX_IRQHandler = Default_Handler
|
||||||
|
#pragma weak CAN1_RX0_IRQHandler = Default_Handler
|
||||||
|
#pragma weak CAN1_RX1_IRQHandler = Default_Handler
|
||||||
|
#pragma weak CAN1_SCE_IRQHandler = Default_Handler
|
||||||
|
#pragma weak EXTI9_5_IRQHandler = Default_Handler
|
||||||
|
#pragma weak TIM1_BRK_TIM9_IRQHandler = Default_Handler
|
||||||
|
#pragma weak TIM1_UP_TIM10_IRQHandler = Default_Handler
|
||||||
|
#pragma weak TIM1_TRG_COM_TIM11_IRQHandler = Default_Handler
|
||||||
|
#pragma weak TIM1_CC_IRQHandler = Default_Handler
|
||||||
|
#pragma weak TIM2_IRQHandler = Default_Handler
|
||||||
|
#pragma weak TIM3_IRQHandler = Default_Handler
|
||||||
|
#pragma weak TIM4_IRQHandler = Default_Handler
|
||||||
|
#pragma weak I2C1_EV_IRQHandler = Default_Handler
|
||||||
|
#pragma weak I2C1_ER_IRQHandler = Default_Handler
|
||||||
|
#pragma weak I2C2_EV_IRQHandler = Default_Handler
|
||||||
|
#pragma weak I2C2_ER_IRQHandler = Default_Handler
|
||||||
|
#pragma weak SPI1_IRQHandler = Default_Handler
|
||||||
|
#pragma weak SPI2_IRQHandler = Default_Handler
|
||||||
|
#pragma weak USART1_IRQHandler = Default_Handler
|
||||||
|
#pragma weak USART2_IRQHandler = Default_Handler
|
||||||
|
#pragma weak USART3_IRQHandler = Default_Handler
|
||||||
|
#pragma weak EXTI15_10_IRQHandler = Default_Handler
|
||||||
|
#pragma weak RTC_Alarm_IRQHandler = Default_Handler
|
||||||
|
#pragma weak OTG_FS_WKUP_IRQHandler = Default_Handler
|
||||||
|
#pragma weak TIM8_BRK_TIM12_IRQHandler = Default_Handler
|
||||||
|
#pragma weak TIM8_UP_TIM13_IRQHandler = Default_Handler
|
||||||
|
#pragma weak TIM8_TRG_COM_TIM14_IRQHandler = Default_Handler
|
||||||
|
#pragma weak TIM8_CC_IRQHandler = Default_Handler
|
||||||
|
#pragma weak DMA1_Stream7_IRQHandler = Default_Handler
|
||||||
|
#pragma weak FSMC_IRQHandler = Default_Handler
|
||||||
|
#pragma weak SDIO_IRQHandler = Default_Handler
|
||||||
|
#pragma weak TIM5_IRQHandler = Default_Handler
|
||||||
|
#pragma weak SPI3_IRQHandler = Default_Handler
|
||||||
|
#pragma weak UART4_IRQHandler = Default_Handler
|
||||||
|
#pragma weak UART5_IRQHandler = Default_Handler
|
||||||
|
#pragma weak TIM6_DAC_IRQHandler = Default_Handler
|
||||||
|
#pragma weak TIM7_IRQHandler = Default_Handler
|
||||||
|
#pragma weak DMA2_Stream0_IRQHandler = Default_Handler
|
||||||
|
#pragma weak DMA2_Stream1_IRQHandler = Default_Handler
|
||||||
|
#pragma weak DMA2_Stream2_IRQHandler = Default_Handler
|
||||||
|
#pragma weak DMA2_Stream3_IRQHandler = Default_Handler
|
||||||
|
#pragma weak DMA2_Stream4_IRQHandler = Default_Handler
|
||||||
|
#pragma weak ETH_IRQHandler = Default_Handler
|
||||||
|
#pragma weak ETH_WKUP_IRQHandler = Default_Handler
|
||||||
|
#pragma weak CAN2_TX_IRQHandler = Default_Handler
|
||||||
|
#pragma weak CAN2_RX0_IRQHandler = Default_Handler
|
||||||
|
#pragma weak CAN2_RX1_IRQHandler = Default_Handler
|
||||||
|
#pragma weak CAN2_SCE_IRQHandler = Default_Handler
|
||||||
|
#pragma weak OTG_FS_IRQHandler = Default_Handler
|
||||||
|
#pragma weak DMA2_Stream5_IRQHandler = Default_Handler
|
||||||
|
#pragma weak DMA2_Stream6_IRQHandler = Default_Handler
|
||||||
|
#pragma weak DMA2_Stream7_IRQHandler = Default_Handler
|
||||||
|
#pragma weak USART6_IRQHandler = Default_Handler
|
||||||
|
#pragma weak I2C3_EV_IRQHandler = Default_Handler
|
||||||
|
#pragma weak I2C3_ER_IRQHandler = Default_Handler
|
||||||
|
#pragma weak OTG_HS_EP1_OUT_IRQHandler = Default_Handler
|
||||||
|
#pragma weak OTG_HS_EP1_IN_IRQHandler = Default_Handler
|
||||||
|
#pragma weak OTG_HS_WKUP_IRQHandler = Default_Handler
|
||||||
|
#pragma weak OTG_HS_IRQHandler = Default_Handler
|
||||||
|
#pragma weak DCMI_IRQHandler = Default_Handler
|
||||||
|
#pragma weak CRYP_IRQHandler = Default_Handler
|
||||||
|
#pragma weak HASH_RNG_IRQHandler = Default_Handler
|
||||||
|
#pragma weak FPU_IRQHandler = Default_Handler
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This is the code that gets called when the processor receives an
|
||||||
|
* unexpected interrupt. This simply enters an infinite loop,
|
||||||
|
* preserving the system state for examination by a debugger.
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
static void Default_Handler(void)
|
||||||
|
{
|
||||||
|
/* Go into an infinite loop. */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************** (C) COPYRIGHT 2009 Coocox ************END OF FILE*****/
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,78 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file Project/STM32F4xx_StdPeriph_Templates/stm32f4xx_conf.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @version V1.7.1
|
||||||
|
* @date 20-May-2016
|
||||||
|
* @brief Library configuration file.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
|
||||||
|
*
|
||||||
|
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.st.com/software_license_agreement_liberty_v2
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __STM32F4xx_CONF_H
|
||||||
|
#define __STM32F4xx_CONF_H
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
/* Uncomment the line below to enable peripheral header file inclusion */
|
||||||
|
#include "stm32f4xx_adc.h"
|
||||||
|
#include "stm32f4xx_dac.h"
|
||||||
|
#include "stm32f4xx_gpio.h"
|
||||||
|
#include "stm32f4xx_rcc.h"
|
||||||
|
#include "stm32f4xx_tim.h"
|
||||||
|
#include "stm32f4xx_usart.h"
|
||||||
|
#include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */
|
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If an external clock source is used, then the value of the following define
|
||||||
|
should be set to the value of the external clock source, else, if no external
|
||||||
|
clock is used, keep this define commented */
|
||||||
|
/*#define I2S_EXTERNAL_CLOCK_VAL 12288000 */ /* Value of the external clock in Hz */
|
||||||
|
|
||||||
|
|
||||||
|
/* Uncomment the line below to expanse the "assert_param" macro in the
|
||||||
|
Standard Peripheral Library drivers code */
|
||||||
|
/* #define USE_FULL_ASSERT 1 */
|
||||||
|
|
||||||
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
|
#ifdef USE_FULL_ASSERT
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The assert_param macro is used for function's parameters check.
|
||||||
|
* @param expr: If expr is false, it calls assert_failed function
|
||||||
|
* which reports the name of the source file and the source
|
||||||
|
* line number of the call that failed.
|
||||||
|
* If expr is true, it returns no value.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
|
||||||
|
/* Exported functions ------------------------------------------------------- */
|
||||||
|
void assert_failed(uint8_t* file, uint32_t line);
|
||||||
|
#else
|
||||||
|
#define assert_param(expr) ((void)0)
|
||||||
|
#endif /* USE_FULL_ASSERT */
|
||||||
|
|
||||||
|
#endif /* __STM32F4xx_CONF_H */
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,105 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file system_stm32f4xx.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @version V1.7.0
|
||||||
|
* @date 22-April-2016
|
||||||
|
* @brief CMSIS Cortex-M4 Device System Source File for STM32F4xx devices.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||||
|
*
|
||||||
|
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.st.com/software_license_agreement_liberty_v2
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup CMSIS
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup stm32f4xx_system
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Define to prevent recursive inclusion
|
||||||
|
*/
|
||||||
|
#ifndef __SYSTEM_STM32F4XX_H
|
||||||
|
#define __SYSTEM_STM32F4XX_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** @addtogroup STM32F4xx_System_Includes
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @addtogroup STM32F4xx_System_Exported_types
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup STM32F4xx_System_Exported_Constants
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup STM32F4xx_System_Exported_Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup STM32F4xx_System_Exported_Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void SystemInit(void);
|
||||||
|
extern void SystemCoreClockUpdate(void);
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*__SYSTEM_STM32F4XX_H */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
Binary file not shown.
@@ -0,0 +1,21 @@
|
|||||||
|
STM32F4XX library for MMDVM project
|
||||||
|
|
||||||
|
This is the STM32F4XX_Lib directory structure with just the needed code for MMDVM.
|
||||||
|
Copy this STM32F4XX_Lib directory inside the MMDVM source code project. You have to
|
||||||
|
conserve the STM32F4XX_Lib folder name: MMDVM/STM32F4XX_Lib
|
||||||
|
|
||||||
|
The source of this package can be found here:
|
||||||
|
http://www.st.com/en/embedded-software/stsw-stm32065.html
|
||||||
|
|
||||||
|
In order to run the MMDVM firmware correctly, there are the following modifications
|
||||||
|
already done in this package:
|
||||||
|
|
||||||
|
1) STM32F4XX_Lib/Device/startup/startup_stm32f4xx.c :
|
||||||
|
- Added C++ global constructors support
|
||||||
|
- Changed initial stack pointer
|
||||||
|
|
||||||
|
2) STM32F4XX_Lib/Device/system_stm32f4xx.c :
|
||||||
|
- Changed PLL_M definition (support "integer" only crystal frequencies: 8, 12, 16 MHz, etc)
|
||||||
|
|
||||||
|
3) STM32F4XX_Lib/Device/stm32f4xx_conf.h :
|
||||||
|
- Peripheral header file inclusions
|
||||||
@@ -0,0 +1,178 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file misc.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @version V1.7.1
|
||||||
|
* @date 20-May-2016
|
||||||
|
* @brief This file contains all the functions prototypes for the miscellaneous
|
||||||
|
* firmware library functions (add-on to CMSIS functions).
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
|
||||||
|
*
|
||||||
|
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.st.com/software_license_agreement_liberty_v2
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __MISC_H
|
||||||
|
#define __MISC_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32F4xx_StdPeriph_Driver
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup MISC
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief NVIC Init Structure definition
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled.
|
||||||
|
This parameter can be an enumerator of @ref IRQn_Type
|
||||||
|
enumeration (For the complete STM32 Devices IRQ Channels
|
||||||
|
list, please refer to stm32f4xx.h file) */
|
||||||
|
|
||||||
|
uint8_t NVIC_IRQChannelPreemptionPriority; /*!< Specifies the pre-emption priority for the IRQ channel
|
||||||
|
specified in NVIC_IRQChannel. This parameter can be a value
|
||||||
|
between 0 and 15 as described in the table @ref MISC_NVIC_Priority_Table
|
||||||
|
A lower priority value indicates a higher priority */
|
||||||
|
|
||||||
|
uint8_t NVIC_IRQChannelSubPriority; /*!< Specifies the subpriority level for the IRQ channel specified
|
||||||
|
in NVIC_IRQChannel. This parameter can be a value
|
||||||
|
between 0 and 15 as described in the table @ref MISC_NVIC_Priority_Table
|
||||||
|
A lower priority value indicates a higher priority */
|
||||||
|
|
||||||
|
FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel
|
||||||
|
will be enabled or disabled.
|
||||||
|
This parameter can be set either to ENABLE or DISABLE */
|
||||||
|
} NVIC_InitTypeDef;
|
||||||
|
|
||||||
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
|
||||||
|
/** @defgroup MISC_Exported_Constants
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup MISC_Vector_Table_Base
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NVIC_VectTab_RAM ((uint32_t)0x20000000)
|
||||||
|
#define NVIC_VectTab_FLASH ((uint32_t)0x08000000)
|
||||||
|
#define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == NVIC_VectTab_RAM) || \
|
||||||
|
((VECTTAB) == NVIC_VectTab_FLASH))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup MISC_System_Low_Power
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NVIC_LP_SEVONPEND ((uint8_t)0x10)
|
||||||
|
#define NVIC_LP_SLEEPDEEP ((uint8_t)0x04)
|
||||||
|
#define NVIC_LP_SLEEPONEXIT ((uint8_t)0x02)
|
||||||
|
#define IS_NVIC_LP(LP) (((LP) == NVIC_LP_SEVONPEND) || \
|
||||||
|
((LP) == NVIC_LP_SLEEPDEEP) || \
|
||||||
|
((LP) == NVIC_LP_SLEEPONEXIT))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup MISC_Preemption_Priority_Group
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority
|
||||||
|
4 bits for subpriority */
|
||||||
|
#define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority
|
||||||
|
3 bits for subpriority */
|
||||||
|
#define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority
|
||||||
|
2 bits for subpriority */
|
||||||
|
#define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority
|
||||||
|
1 bits for subpriority */
|
||||||
|
#define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority
|
||||||
|
0 bits for subpriority */
|
||||||
|
|
||||||
|
#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PriorityGroup_0) || \
|
||||||
|
((GROUP) == NVIC_PriorityGroup_1) || \
|
||||||
|
((GROUP) == NVIC_PriorityGroup_2) || \
|
||||||
|
((GROUP) == NVIC_PriorityGroup_3) || \
|
||||||
|
((GROUP) == NVIC_PriorityGroup_4))
|
||||||
|
|
||||||
|
#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x10)
|
||||||
|
|
||||||
|
#define IS_NVIC_SUB_PRIORITY(PRIORITY) ((PRIORITY) < 0x10)
|
||||||
|
|
||||||
|
#define IS_NVIC_OFFSET(OFFSET) ((OFFSET) < 0x000FFFFF)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup MISC_SysTick_clock_source
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB)
|
||||||
|
#define SysTick_CLKSource_HCLK ((uint32_t)0x00000004)
|
||||||
|
#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \
|
||||||
|
((SOURCE) == SysTick_CLKSource_HCLK_Div8))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
|
||||||
|
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
|
||||||
|
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
|
||||||
|
void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);
|
||||||
|
void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);
|
||||||
|
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __MISC_H */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
@@ -0,0 +1,656 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f4xx_adc.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @version V1.7.1
|
||||||
|
* @date 20-May-2016
|
||||||
|
* @brief This file contains all the functions prototypes for the ADC firmware
|
||||||
|
* library.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
|
||||||
|
*
|
||||||
|
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.st.com/software_license_agreement_liberty_v2
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __STM32F4xx_ADC_H
|
||||||
|
#define __STM32F4xx_ADC_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32F4xx_StdPeriph_Driver
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup ADC
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ADC Init structure definition
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t ADC_Resolution; /*!< Configures the ADC resolution dual mode.
|
||||||
|
This parameter can be a value of @ref ADC_resolution */
|
||||||
|
FunctionalState ADC_ScanConvMode; /*!< Specifies whether the conversion
|
||||||
|
is performed in Scan (multichannels)
|
||||||
|
or Single (one channel) mode.
|
||||||
|
This parameter can be set to ENABLE or DISABLE */
|
||||||
|
FunctionalState ADC_ContinuousConvMode; /*!< Specifies whether the conversion
|
||||||
|
is performed in Continuous or Single mode.
|
||||||
|
This parameter can be set to ENABLE or DISABLE. */
|
||||||
|
uint32_t ADC_ExternalTrigConvEdge; /*!< Select the external trigger edge and
|
||||||
|
enable the trigger of a regular group.
|
||||||
|
This parameter can be a value of
|
||||||
|
@ref ADC_external_trigger_edge_for_regular_channels_conversion */
|
||||||
|
uint32_t ADC_ExternalTrigConv; /*!< Select the external event used to trigger
|
||||||
|
the start of conversion of a regular group.
|
||||||
|
This parameter can be a value of
|
||||||
|
@ref ADC_extrenal_trigger_sources_for_regular_channels_conversion */
|
||||||
|
uint32_t ADC_DataAlign; /*!< Specifies whether the ADC data alignment
|
||||||
|
is left or right. This parameter can be
|
||||||
|
a value of @ref ADC_data_align */
|
||||||
|
uint8_t ADC_NbrOfConversion; /*!< Specifies the number of ADC conversions
|
||||||
|
that will be done using the sequencer for
|
||||||
|
regular channel group.
|
||||||
|
This parameter must range from 1 to 16. */
|
||||||
|
}ADC_InitTypeDef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ADC Common Init structure definition
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t ADC_Mode; /*!< Configures the ADC to operate in
|
||||||
|
independent or multi mode.
|
||||||
|
This parameter can be a value of @ref ADC_Common_mode */
|
||||||
|
uint32_t ADC_Prescaler; /*!< Select the frequency of the clock
|
||||||
|
to the ADC. The clock is common for all the ADCs.
|
||||||
|
This parameter can be a value of @ref ADC_Prescaler */
|
||||||
|
uint32_t ADC_DMAAccessMode; /*!< Configures the Direct memory access
|
||||||
|
mode for multi ADC mode.
|
||||||
|
This parameter can be a value of
|
||||||
|
@ref ADC_Direct_memory_access_mode_for_multi_mode */
|
||||||
|
uint32_t ADC_TwoSamplingDelay; /*!< Configures the Delay between 2 sampling phases.
|
||||||
|
This parameter can be a value of
|
||||||
|
@ref ADC_delay_between_2_sampling_phases */
|
||||||
|
|
||||||
|
}ADC_CommonInitTypeDef;
|
||||||
|
|
||||||
|
|
||||||
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
|
||||||
|
/** @defgroup ADC_Exported_Constants
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define IS_ADC_ALL_PERIPH(PERIPH) (((PERIPH) == ADC1) || \
|
||||||
|
((PERIPH) == ADC2) || \
|
||||||
|
((PERIPH) == ADC3))
|
||||||
|
|
||||||
|
/** @defgroup ADC_Common_mode
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define ADC_Mode_Independent ((uint32_t)0x00000000)
|
||||||
|
#define ADC_DualMode_RegSimult_InjecSimult ((uint32_t)0x00000001)
|
||||||
|
#define ADC_DualMode_RegSimult_AlterTrig ((uint32_t)0x00000002)
|
||||||
|
#define ADC_DualMode_InjecSimult ((uint32_t)0x00000005)
|
||||||
|
#define ADC_DualMode_RegSimult ((uint32_t)0x00000006)
|
||||||
|
#define ADC_DualMode_Interl ((uint32_t)0x00000007)
|
||||||
|
#define ADC_DualMode_AlterTrig ((uint32_t)0x00000009)
|
||||||
|
#define ADC_TripleMode_RegSimult_InjecSimult ((uint32_t)0x00000011)
|
||||||
|
#define ADC_TripleMode_RegSimult_AlterTrig ((uint32_t)0x00000012)
|
||||||
|
#define ADC_TripleMode_InjecSimult ((uint32_t)0x00000015)
|
||||||
|
#define ADC_TripleMode_RegSimult ((uint32_t)0x00000016)
|
||||||
|
#define ADC_TripleMode_Interl ((uint32_t)0x00000017)
|
||||||
|
#define ADC_TripleMode_AlterTrig ((uint32_t)0x00000019)
|
||||||
|
#define IS_ADC_MODE(MODE) (((MODE) == ADC_Mode_Independent) || \
|
||||||
|
((MODE) == ADC_DualMode_RegSimult_InjecSimult) || \
|
||||||
|
((MODE) == ADC_DualMode_RegSimult_AlterTrig) || \
|
||||||
|
((MODE) == ADC_DualMode_InjecSimult) || \
|
||||||
|
((MODE) == ADC_DualMode_RegSimult) || \
|
||||||
|
((MODE) == ADC_DualMode_Interl) || \
|
||||||
|
((MODE) == ADC_DualMode_AlterTrig) || \
|
||||||
|
((MODE) == ADC_TripleMode_RegSimult_InjecSimult) || \
|
||||||
|
((MODE) == ADC_TripleMode_RegSimult_AlterTrig) || \
|
||||||
|
((MODE) == ADC_TripleMode_InjecSimult) || \
|
||||||
|
((MODE) == ADC_TripleMode_RegSimult) || \
|
||||||
|
((MODE) == ADC_TripleMode_Interl) || \
|
||||||
|
((MODE) == ADC_TripleMode_AlterTrig))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup ADC_Prescaler
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define ADC_Prescaler_Div2 ((uint32_t)0x00000000)
|
||||||
|
#define ADC_Prescaler_Div4 ((uint32_t)0x00010000)
|
||||||
|
#define ADC_Prescaler_Div6 ((uint32_t)0x00020000)
|
||||||
|
#define ADC_Prescaler_Div8 ((uint32_t)0x00030000)
|
||||||
|
#define IS_ADC_PRESCALER(PRESCALER) (((PRESCALER) == ADC_Prescaler_Div2) || \
|
||||||
|
((PRESCALER) == ADC_Prescaler_Div4) || \
|
||||||
|
((PRESCALER) == ADC_Prescaler_Div6) || \
|
||||||
|
((PRESCALER) == ADC_Prescaler_Div8))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup ADC_Direct_memory_access_mode_for_multi_mode
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define ADC_DMAAccessMode_Disabled ((uint32_t)0x00000000) /* DMA mode disabled */
|
||||||
|
#define ADC_DMAAccessMode_1 ((uint32_t)0x00004000) /* DMA mode 1 enabled (2 / 3 half-words one by one - 1 then 2 then 3)*/
|
||||||
|
#define ADC_DMAAccessMode_2 ((uint32_t)0x00008000) /* DMA mode 2 enabled (2 / 3 half-words by pairs - 2&1 then 1&3 then 3&2)*/
|
||||||
|
#define ADC_DMAAccessMode_3 ((uint32_t)0x0000C000) /* DMA mode 3 enabled (2 / 3 bytes by pairs - 2&1 then 1&3 then 3&2) */
|
||||||
|
#define IS_ADC_DMA_ACCESS_MODE(MODE) (((MODE) == ADC_DMAAccessMode_Disabled) || \
|
||||||
|
((MODE) == ADC_DMAAccessMode_1) || \
|
||||||
|
((MODE) == ADC_DMAAccessMode_2) || \
|
||||||
|
((MODE) == ADC_DMAAccessMode_3))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup ADC_delay_between_2_sampling_phases
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define ADC_TwoSamplingDelay_5Cycles ((uint32_t)0x00000000)
|
||||||
|
#define ADC_TwoSamplingDelay_6Cycles ((uint32_t)0x00000100)
|
||||||
|
#define ADC_TwoSamplingDelay_7Cycles ((uint32_t)0x00000200)
|
||||||
|
#define ADC_TwoSamplingDelay_8Cycles ((uint32_t)0x00000300)
|
||||||
|
#define ADC_TwoSamplingDelay_9Cycles ((uint32_t)0x00000400)
|
||||||
|
#define ADC_TwoSamplingDelay_10Cycles ((uint32_t)0x00000500)
|
||||||
|
#define ADC_TwoSamplingDelay_11Cycles ((uint32_t)0x00000600)
|
||||||
|
#define ADC_TwoSamplingDelay_12Cycles ((uint32_t)0x00000700)
|
||||||
|
#define ADC_TwoSamplingDelay_13Cycles ((uint32_t)0x00000800)
|
||||||
|
#define ADC_TwoSamplingDelay_14Cycles ((uint32_t)0x00000900)
|
||||||
|
#define ADC_TwoSamplingDelay_15Cycles ((uint32_t)0x00000A00)
|
||||||
|
#define ADC_TwoSamplingDelay_16Cycles ((uint32_t)0x00000B00)
|
||||||
|
#define ADC_TwoSamplingDelay_17Cycles ((uint32_t)0x00000C00)
|
||||||
|
#define ADC_TwoSamplingDelay_18Cycles ((uint32_t)0x00000D00)
|
||||||
|
#define ADC_TwoSamplingDelay_19Cycles ((uint32_t)0x00000E00)
|
||||||
|
#define ADC_TwoSamplingDelay_20Cycles ((uint32_t)0x00000F00)
|
||||||
|
#define IS_ADC_SAMPLING_DELAY(DELAY) (((DELAY) == ADC_TwoSamplingDelay_5Cycles) || \
|
||||||
|
((DELAY) == ADC_TwoSamplingDelay_6Cycles) || \
|
||||||
|
((DELAY) == ADC_TwoSamplingDelay_7Cycles) || \
|
||||||
|
((DELAY) == ADC_TwoSamplingDelay_8Cycles) || \
|
||||||
|
((DELAY) == ADC_TwoSamplingDelay_9Cycles) || \
|
||||||
|
((DELAY) == ADC_TwoSamplingDelay_10Cycles) || \
|
||||||
|
((DELAY) == ADC_TwoSamplingDelay_11Cycles) || \
|
||||||
|
((DELAY) == ADC_TwoSamplingDelay_12Cycles) || \
|
||||||
|
((DELAY) == ADC_TwoSamplingDelay_13Cycles) || \
|
||||||
|
((DELAY) == ADC_TwoSamplingDelay_14Cycles) || \
|
||||||
|
((DELAY) == ADC_TwoSamplingDelay_15Cycles) || \
|
||||||
|
((DELAY) == ADC_TwoSamplingDelay_16Cycles) || \
|
||||||
|
((DELAY) == ADC_TwoSamplingDelay_17Cycles) || \
|
||||||
|
((DELAY) == ADC_TwoSamplingDelay_18Cycles) || \
|
||||||
|
((DELAY) == ADC_TwoSamplingDelay_19Cycles) || \
|
||||||
|
((DELAY) == ADC_TwoSamplingDelay_20Cycles))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup ADC_resolution
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define ADC_Resolution_12b ((uint32_t)0x00000000)
|
||||||
|
#define ADC_Resolution_10b ((uint32_t)0x01000000)
|
||||||
|
#define ADC_Resolution_8b ((uint32_t)0x02000000)
|
||||||
|
#define ADC_Resolution_6b ((uint32_t)0x03000000)
|
||||||
|
#define IS_ADC_RESOLUTION(RESOLUTION) (((RESOLUTION) == ADC_Resolution_12b) || \
|
||||||
|
((RESOLUTION) == ADC_Resolution_10b) || \
|
||||||
|
((RESOLUTION) == ADC_Resolution_8b) || \
|
||||||
|
((RESOLUTION) == ADC_Resolution_6b))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup ADC_external_trigger_edge_for_regular_channels_conversion
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define ADC_ExternalTrigConvEdge_None ((uint32_t)0x00000000)
|
||||||
|
#define ADC_ExternalTrigConvEdge_Rising ((uint32_t)0x10000000)
|
||||||
|
#define ADC_ExternalTrigConvEdge_Falling ((uint32_t)0x20000000)
|
||||||
|
#define ADC_ExternalTrigConvEdge_RisingFalling ((uint32_t)0x30000000)
|
||||||
|
#define IS_ADC_EXT_TRIG_EDGE(EDGE) (((EDGE) == ADC_ExternalTrigConvEdge_None) || \
|
||||||
|
((EDGE) == ADC_ExternalTrigConvEdge_Rising) || \
|
||||||
|
((EDGE) == ADC_ExternalTrigConvEdge_Falling) || \
|
||||||
|
((EDGE) == ADC_ExternalTrigConvEdge_RisingFalling))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup ADC_extrenal_trigger_sources_for_regular_channels_conversion
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define ADC_ExternalTrigConv_T1_CC1 ((uint32_t)0x00000000)
|
||||||
|
#define ADC_ExternalTrigConv_T1_CC2 ((uint32_t)0x01000000)
|
||||||
|
#define ADC_ExternalTrigConv_T1_CC3 ((uint32_t)0x02000000)
|
||||||
|
#define ADC_ExternalTrigConv_T2_CC2 ((uint32_t)0x03000000)
|
||||||
|
#define ADC_ExternalTrigConv_T2_CC3 ((uint32_t)0x04000000)
|
||||||
|
#define ADC_ExternalTrigConv_T2_CC4 ((uint32_t)0x05000000)
|
||||||
|
#define ADC_ExternalTrigConv_T2_TRGO ((uint32_t)0x06000000)
|
||||||
|
#define ADC_ExternalTrigConv_T3_CC1 ((uint32_t)0x07000000)
|
||||||
|
#define ADC_ExternalTrigConv_T3_TRGO ((uint32_t)0x08000000)
|
||||||
|
#define ADC_ExternalTrigConv_T4_CC4 ((uint32_t)0x09000000)
|
||||||
|
#define ADC_ExternalTrigConv_T5_CC1 ((uint32_t)0x0A000000)
|
||||||
|
#define ADC_ExternalTrigConv_T5_CC2 ((uint32_t)0x0B000000)
|
||||||
|
#define ADC_ExternalTrigConv_T5_CC3 ((uint32_t)0x0C000000)
|
||||||
|
#define ADC_ExternalTrigConv_T8_CC1 ((uint32_t)0x0D000000)
|
||||||
|
#define ADC_ExternalTrigConv_T8_TRGO ((uint32_t)0x0E000000)
|
||||||
|
#define ADC_ExternalTrigConv_Ext_IT11 ((uint32_t)0x0F000000)
|
||||||
|
#define IS_ADC_EXT_TRIG(REGTRIG) (((REGTRIG) == ADC_ExternalTrigConv_T1_CC1) || \
|
||||||
|
((REGTRIG) == ADC_ExternalTrigConv_T1_CC2) || \
|
||||||
|
((REGTRIG) == ADC_ExternalTrigConv_T1_CC3) || \
|
||||||
|
((REGTRIG) == ADC_ExternalTrigConv_T2_CC2) || \
|
||||||
|
((REGTRIG) == ADC_ExternalTrigConv_T2_CC3) || \
|
||||||
|
((REGTRIG) == ADC_ExternalTrigConv_T2_CC4) || \
|
||||||
|
((REGTRIG) == ADC_ExternalTrigConv_T2_TRGO) || \
|
||||||
|
((REGTRIG) == ADC_ExternalTrigConv_T3_CC1) || \
|
||||||
|
((REGTRIG) == ADC_ExternalTrigConv_T3_TRGO) || \
|
||||||
|
((REGTRIG) == ADC_ExternalTrigConv_T4_CC4) || \
|
||||||
|
((REGTRIG) == ADC_ExternalTrigConv_T5_CC1) || \
|
||||||
|
((REGTRIG) == ADC_ExternalTrigConv_T5_CC2) || \
|
||||||
|
((REGTRIG) == ADC_ExternalTrigConv_T5_CC3) || \
|
||||||
|
((REGTRIG) == ADC_ExternalTrigConv_T8_CC1) || \
|
||||||
|
((REGTRIG) == ADC_ExternalTrigConv_T8_TRGO) || \
|
||||||
|
((REGTRIG) == ADC_ExternalTrigConv_Ext_IT11))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup ADC_data_align
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define ADC_DataAlign_Right ((uint32_t)0x00000000)
|
||||||
|
#define ADC_DataAlign_Left ((uint32_t)0x00000800)
|
||||||
|
#define IS_ADC_DATA_ALIGN(ALIGN) (((ALIGN) == ADC_DataAlign_Right) || \
|
||||||
|
((ALIGN) == ADC_DataAlign_Left))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup ADC_channels
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define ADC_Channel_0 ((uint8_t)0x00)
|
||||||
|
#define ADC_Channel_1 ((uint8_t)0x01)
|
||||||
|
#define ADC_Channel_2 ((uint8_t)0x02)
|
||||||
|
#define ADC_Channel_3 ((uint8_t)0x03)
|
||||||
|
#define ADC_Channel_4 ((uint8_t)0x04)
|
||||||
|
#define ADC_Channel_5 ((uint8_t)0x05)
|
||||||
|
#define ADC_Channel_6 ((uint8_t)0x06)
|
||||||
|
#define ADC_Channel_7 ((uint8_t)0x07)
|
||||||
|
#define ADC_Channel_8 ((uint8_t)0x08)
|
||||||
|
#define ADC_Channel_9 ((uint8_t)0x09)
|
||||||
|
#define ADC_Channel_10 ((uint8_t)0x0A)
|
||||||
|
#define ADC_Channel_11 ((uint8_t)0x0B)
|
||||||
|
#define ADC_Channel_12 ((uint8_t)0x0C)
|
||||||
|
#define ADC_Channel_13 ((uint8_t)0x0D)
|
||||||
|
#define ADC_Channel_14 ((uint8_t)0x0E)
|
||||||
|
#define ADC_Channel_15 ((uint8_t)0x0F)
|
||||||
|
#define ADC_Channel_16 ((uint8_t)0x10)
|
||||||
|
#define ADC_Channel_17 ((uint8_t)0x11)
|
||||||
|
#define ADC_Channel_18 ((uint8_t)0x12)
|
||||||
|
|
||||||
|
#if defined (STM32F40_41xxx) || defined(STM32F412xG)
|
||||||
|
#define ADC_Channel_TempSensor ((uint8_t)ADC_Channel_16)
|
||||||
|
#endif /* STM32F40_41xxx || STM32F412xG */
|
||||||
|
|
||||||
|
#if defined (STM32F427_437xx) || defined (STM32F429_439xx) || defined (STM32F401xx) || defined (STM32F410xx) || defined (STM32F411xE)
|
||||||
|
#define ADC_Channel_TempSensor ((uint8_t)ADC_Channel_18)
|
||||||
|
#endif /* STM32F427_437xx || STM32F429_439xx || STM32F401xx || STM32F410xx || STM32F411xE */
|
||||||
|
|
||||||
|
#define ADC_Channel_Vrefint ((uint8_t)ADC_Channel_17)
|
||||||
|
#define ADC_Channel_Vbat ((uint8_t)ADC_Channel_18)
|
||||||
|
|
||||||
|
#define IS_ADC_CHANNEL(CHANNEL) (((CHANNEL) == ADC_Channel_0) || \
|
||||||
|
((CHANNEL) == ADC_Channel_1) || \
|
||||||
|
((CHANNEL) == ADC_Channel_2) || \
|
||||||
|
((CHANNEL) == ADC_Channel_3) || \
|
||||||
|
((CHANNEL) == ADC_Channel_4) || \
|
||||||
|
((CHANNEL) == ADC_Channel_5) || \
|
||||||
|
((CHANNEL) == ADC_Channel_6) || \
|
||||||
|
((CHANNEL) == ADC_Channel_7) || \
|
||||||
|
((CHANNEL) == ADC_Channel_8) || \
|
||||||
|
((CHANNEL) == ADC_Channel_9) || \
|
||||||
|
((CHANNEL) == ADC_Channel_10) || \
|
||||||
|
((CHANNEL) == ADC_Channel_11) || \
|
||||||
|
((CHANNEL) == ADC_Channel_12) || \
|
||||||
|
((CHANNEL) == ADC_Channel_13) || \
|
||||||
|
((CHANNEL) == ADC_Channel_14) || \
|
||||||
|
((CHANNEL) == ADC_Channel_15) || \
|
||||||
|
((CHANNEL) == ADC_Channel_16) || \
|
||||||
|
((CHANNEL) == ADC_Channel_17) || \
|
||||||
|
((CHANNEL) == ADC_Channel_18))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup ADC_sampling_times
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define ADC_SampleTime_3Cycles ((uint8_t)0x00)
|
||||||
|
#define ADC_SampleTime_15Cycles ((uint8_t)0x01)
|
||||||
|
#define ADC_SampleTime_28Cycles ((uint8_t)0x02)
|
||||||
|
#define ADC_SampleTime_56Cycles ((uint8_t)0x03)
|
||||||
|
#define ADC_SampleTime_84Cycles ((uint8_t)0x04)
|
||||||
|
#define ADC_SampleTime_112Cycles ((uint8_t)0x05)
|
||||||
|
#define ADC_SampleTime_144Cycles ((uint8_t)0x06)
|
||||||
|
#define ADC_SampleTime_480Cycles ((uint8_t)0x07)
|
||||||
|
#define IS_ADC_SAMPLE_TIME(TIME) (((TIME) == ADC_SampleTime_3Cycles) || \
|
||||||
|
((TIME) == ADC_SampleTime_15Cycles) || \
|
||||||
|
((TIME) == ADC_SampleTime_28Cycles) || \
|
||||||
|
((TIME) == ADC_SampleTime_56Cycles) || \
|
||||||
|
((TIME) == ADC_SampleTime_84Cycles) || \
|
||||||
|
((TIME) == ADC_SampleTime_112Cycles) || \
|
||||||
|
((TIME) == ADC_SampleTime_144Cycles) || \
|
||||||
|
((TIME) == ADC_SampleTime_480Cycles))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup ADC_external_trigger_edge_for_injected_channels_conversion
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define ADC_ExternalTrigInjecConvEdge_None ((uint32_t)0x00000000)
|
||||||
|
#define ADC_ExternalTrigInjecConvEdge_Rising ((uint32_t)0x00100000)
|
||||||
|
#define ADC_ExternalTrigInjecConvEdge_Falling ((uint32_t)0x00200000)
|
||||||
|
#define ADC_ExternalTrigInjecConvEdge_RisingFalling ((uint32_t)0x00300000)
|
||||||
|
#define IS_ADC_EXT_INJEC_TRIG_EDGE(EDGE) (((EDGE) == ADC_ExternalTrigInjecConvEdge_None) || \
|
||||||
|
((EDGE) == ADC_ExternalTrigInjecConvEdge_Rising) || \
|
||||||
|
((EDGE) == ADC_ExternalTrigInjecConvEdge_Falling) || \
|
||||||
|
((EDGE) == ADC_ExternalTrigInjecConvEdge_RisingFalling))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup ADC_extrenal_trigger_sources_for_injected_channels_conversion
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define ADC_ExternalTrigInjecConv_T1_CC4 ((uint32_t)0x00000000)
|
||||||
|
#define ADC_ExternalTrigInjecConv_T1_TRGO ((uint32_t)0x00010000)
|
||||||
|
#define ADC_ExternalTrigInjecConv_T2_CC1 ((uint32_t)0x00020000)
|
||||||
|
#define ADC_ExternalTrigInjecConv_T2_TRGO ((uint32_t)0x00030000)
|
||||||
|
#define ADC_ExternalTrigInjecConv_T3_CC2 ((uint32_t)0x00040000)
|
||||||
|
#define ADC_ExternalTrigInjecConv_T3_CC4 ((uint32_t)0x00050000)
|
||||||
|
#define ADC_ExternalTrigInjecConv_T4_CC1 ((uint32_t)0x00060000)
|
||||||
|
#define ADC_ExternalTrigInjecConv_T4_CC2 ((uint32_t)0x00070000)
|
||||||
|
#define ADC_ExternalTrigInjecConv_T4_CC3 ((uint32_t)0x00080000)
|
||||||
|
#define ADC_ExternalTrigInjecConv_T4_TRGO ((uint32_t)0x00090000)
|
||||||
|
#define ADC_ExternalTrigInjecConv_T5_CC4 ((uint32_t)0x000A0000)
|
||||||
|
#define ADC_ExternalTrigInjecConv_T5_TRGO ((uint32_t)0x000B0000)
|
||||||
|
#define ADC_ExternalTrigInjecConv_T8_CC2 ((uint32_t)0x000C0000)
|
||||||
|
#define ADC_ExternalTrigInjecConv_T8_CC3 ((uint32_t)0x000D0000)
|
||||||
|
#define ADC_ExternalTrigInjecConv_T8_CC4 ((uint32_t)0x000E0000)
|
||||||
|
#define ADC_ExternalTrigInjecConv_Ext_IT15 ((uint32_t)0x000F0000)
|
||||||
|
#define IS_ADC_EXT_INJEC_TRIG(INJTRIG) (((INJTRIG) == ADC_ExternalTrigInjecConv_T1_CC4) || \
|
||||||
|
((INJTRIG) == ADC_ExternalTrigInjecConv_T1_TRGO) || \
|
||||||
|
((INJTRIG) == ADC_ExternalTrigInjecConv_T2_CC1) || \
|
||||||
|
((INJTRIG) == ADC_ExternalTrigInjecConv_T2_TRGO) || \
|
||||||
|
((INJTRIG) == ADC_ExternalTrigInjecConv_T3_CC2) || \
|
||||||
|
((INJTRIG) == ADC_ExternalTrigInjecConv_T3_CC4) || \
|
||||||
|
((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC1) || \
|
||||||
|
((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC2) || \
|
||||||
|
((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC3) || \
|
||||||
|
((INJTRIG) == ADC_ExternalTrigInjecConv_T4_TRGO) || \
|
||||||
|
((INJTRIG) == ADC_ExternalTrigInjecConv_T5_CC4) || \
|
||||||
|
((INJTRIG) == ADC_ExternalTrigInjecConv_T5_TRGO) || \
|
||||||
|
((INJTRIG) == ADC_ExternalTrigInjecConv_T8_CC2) || \
|
||||||
|
((INJTRIG) == ADC_ExternalTrigInjecConv_T8_CC3) || \
|
||||||
|
((INJTRIG) == ADC_ExternalTrigInjecConv_T8_CC4) || \
|
||||||
|
((INJTRIG) == ADC_ExternalTrigInjecConv_Ext_IT15))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup ADC_injected_channel_selection
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define ADC_InjectedChannel_1 ((uint8_t)0x14)
|
||||||
|
#define ADC_InjectedChannel_2 ((uint8_t)0x18)
|
||||||
|
#define ADC_InjectedChannel_3 ((uint8_t)0x1C)
|
||||||
|
#define ADC_InjectedChannel_4 ((uint8_t)0x20)
|
||||||
|
#define IS_ADC_INJECTED_CHANNEL(CHANNEL) (((CHANNEL) == ADC_InjectedChannel_1) || \
|
||||||
|
((CHANNEL) == ADC_InjectedChannel_2) || \
|
||||||
|
((CHANNEL) == ADC_InjectedChannel_3) || \
|
||||||
|
((CHANNEL) == ADC_InjectedChannel_4))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup ADC_analog_watchdog_selection
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define ADC_AnalogWatchdog_SingleRegEnable ((uint32_t)0x00800200)
|
||||||
|
#define ADC_AnalogWatchdog_SingleInjecEnable ((uint32_t)0x00400200)
|
||||||
|
#define ADC_AnalogWatchdog_SingleRegOrInjecEnable ((uint32_t)0x00C00200)
|
||||||
|
#define ADC_AnalogWatchdog_AllRegEnable ((uint32_t)0x00800000)
|
||||||
|
#define ADC_AnalogWatchdog_AllInjecEnable ((uint32_t)0x00400000)
|
||||||
|
#define ADC_AnalogWatchdog_AllRegAllInjecEnable ((uint32_t)0x00C00000)
|
||||||
|
#define ADC_AnalogWatchdog_None ((uint32_t)0x00000000)
|
||||||
|
#define IS_ADC_ANALOG_WATCHDOG(WATCHDOG) (((WATCHDOG) == ADC_AnalogWatchdog_SingleRegEnable) || \
|
||||||
|
((WATCHDOG) == ADC_AnalogWatchdog_SingleInjecEnable) || \
|
||||||
|
((WATCHDOG) == ADC_AnalogWatchdog_SingleRegOrInjecEnable) || \
|
||||||
|
((WATCHDOG) == ADC_AnalogWatchdog_AllRegEnable) || \
|
||||||
|
((WATCHDOG) == ADC_AnalogWatchdog_AllInjecEnable) || \
|
||||||
|
((WATCHDOG) == ADC_AnalogWatchdog_AllRegAllInjecEnable) || \
|
||||||
|
((WATCHDOG) == ADC_AnalogWatchdog_None))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup ADC_interrupts_definition
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define ADC_IT_EOC ((uint16_t)0x0205)
|
||||||
|
#define ADC_IT_AWD ((uint16_t)0x0106)
|
||||||
|
#define ADC_IT_JEOC ((uint16_t)0x0407)
|
||||||
|
#define ADC_IT_OVR ((uint16_t)0x201A)
|
||||||
|
#define IS_ADC_IT(IT) (((IT) == ADC_IT_EOC) || ((IT) == ADC_IT_AWD) || \
|
||||||
|
((IT) == ADC_IT_JEOC)|| ((IT) == ADC_IT_OVR))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup ADC_flags_definition
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define ADC_FLAG_AWD ((uint8_t)0x01)
|
||||||
|
#define ADC_FLAG_EOC ((uint8_t)0x02)
|
||||||
|
#define ADC_FLAG_JEOC ((uint8_t)0x04)
|
||||||
|
#define ADC_FLAG_JSTRT ((uint8_t)0x08)
|
||||||
|
#define ADC_FLAG_STRT ((uint8_t)0x10)
|
||||||
|
#define ADC_FLAG_OVR ((uint8_t)0x20)
|
||||||
|
|
||||||
|
#define IS_ADC_CLEAR_FLAG(FLAG) ((((FLAG) & (uint8_t)0xC0) == 0x00) && ((FLAG) != 0x00))
|
||||||
|
#define IS_ADC_GET_FLAG(FLAG) (((FLAG) == ADC_FLAG_AWD) || \
|
||||||
|
((FLAG) == ADC_FLAG_EOC) || \
|
||||||
|
((FLAG) == ADC_FLAG_JEOC) || \
|
||||||
|
((FLAG)== ADC_FLAG_JSTRT) || \
|
||||||
|
((FLAG) == ADC_FLAG_STRT) || \
|
||||||
|
((FLAG)== ADC_FLAG_OVR))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup ADC_thresholds
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define IS_ADC_THRESHOLD(THRESHOLD) ((THRESHOLD) <= 0xFFF)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup ADC_injected_offset
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define IS_ADC_OFFSET(OFFSET) ((OFFSET) <= 0xFFF)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup ADC_injected_length
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define IS_ADC_INJECTED_LENGTH(LENGTH) (((LENGTH) >= 0x1) && ((LENGTH) <= 0x4))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup ADC_injected_rank
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define IS_ADC_INJECTED_RANK(RANK) (((RANK) >= 0x1) && ((RANK) <= 0x4))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup ADC_regular_length
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define IS_ADC_REGULAR_LENGTH(LENGTH) (((LENGTH) >= 0x1) && ((LENGTH) <= 0x10))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup ADC_regular_rank
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define IS_ADC_REGULAR_RANK(RANK) (((RANK) >= 0x1) && ((RANK) <= 0x10))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup ADC_regular_discontinuous_mode_number
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define IS_ADC_REGULAR_DISC_NUMBER(NUMBER) (((NUMBER) >= 0x1) && ((NUMBER) <= 0x8))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Function used to set the ADC configuration to the default reset state *****/
|
||||||
|
void ADC_DeInit(void);
|
||||||
|
|
||||||
|
/* Initialization and Configuration functions *********************************/
|
||||||
|
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
|
||||||
|
void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct);
|
||||||
|
void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct);
|
||||||
|
void ADC_CommonStructInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct);
|
||||||
|
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
|
||||||
|
|
||||||
|
/* Analog Watchdog configuration functions ************************************/
|
||||||
|
void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog);
|
||||||
|
void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold,uint16_t LowThreshold);
|
||||||
|
void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel);
|
||||||
|
|
||||||
|
/* Temperature Sensor, Vrefint and VBAT management functions ******************/
|
||||||
|
void ADC_TempSensorVrefintCmd(FunctionalState NewState);
|
||||||
|
void ADC_VBATCmd(FunctionalState NewState);
|
||||||
|
|
||||||
|
/* Regular Channels Configuration functions ***********************************/
|
||||||
|
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
|
||||||
|
void ADC_SoftwareStartConv(ADC_TypeDef* ADCx);
|
||||||
|
FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx);
|
||||||
|
void ADC_EOCOnEachRegularChannelCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
|
||||||
|
void ADC_ContinuousModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
|
||||||
|
void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number);
|
||||||
|
void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
|
||||||
|
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);
|
||||||
|
uint32_t ADC_GetMultiModeConversionValue(void);
|
||||||
|
|
||||||
|
/* Regular Channels DMA Configuration functions *******************************/
|
||||||
|
void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState);
|
||||||
|
void ADC_DMARequestAfterLastTransferCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
|
||||||
|
void ADC_MultiModeDMARequestAfterLastTransferCmd(FunctionalState NewState);
|
||||||
|
|
||||||
|
/* Injected channels Configuration functions **********************************/
|
||||||
|
void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
|
||||||
|
void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length);
|
||||||
|
void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset);
|
||||||
|
void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv);
|
||||||
|
void ADC_ExternalTrigInjectedConvEdgeConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConvEdge);
|
||||||
|
void ADC_SoftwareStartInjectedConv(ADC_TypeDef* ADCx);
|
||||||
|
FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx);
|
||||||
|
void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
|
||||||
|
void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
|
||||||
|
uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel);
|
||||||
|
|
||||||
|
/* Interrupts and flags management functions **********************************/
|
||||||
|
void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState);
|
||||||
|
FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);
|
||||||
|
void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);
|
||||||
|
ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT);
|
||||||
|
void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*__STM32F4xx_ADC_H */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
@@ -0,0 +1,304 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f4xx_dac.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @version V1.7.1
|
||||||
|
* @date 20-May-2016
|
||||||
|
* @brief This file contains all the functions prototypes for the DAC firmware
|
||||||
|
* library.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
|
||||||
|
*
|
||||||
|
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.st.com/software_license_agreement_liberty_v2
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __STM32F4xx_DAC_H
|
||||||
|
#define __STM32F4xx_DAC_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32F4xx_StdPeriph_Driver
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup DAC
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief DAC Init structure definition
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t DAC_Trigger; /*!< Specifies the external trigger for the selected DAC channel.
|
||||||
|
This parameter can be a value of @ref DAC_trigger_selection */
|
||||||
|
|
||||||
|
uint32_t DAC_WaveGeneration; /*!< Specifies whether DAC channel noise waves or triangle waves
|
||||||
|
are generated, or whether no wave is generated.
|
||||||
|
This parameter can be a value of @ref DAC_wave_generation */
|
||||||
|
|
||||||
|
uint32_t DAC_LFSRUnmask_TriangleAmplitude; /*!< Specifies the LFSR mask for noise wave generation or
|
||||||
|
the maximum amplitude triangle generation for the DAC channel.
|
||||||
|
This parameter can be a value of @ref DAC_lfsrunmask_triangleamplitude */
|
||||||
|
|
||||||
|
uint32_t DAC_OutputBuffer; /*!< Specifies whether the DAC channel output buffer is enabled or disabled.
|
||||||
|
This parameter can be a value of @ref DAC_output_buffer */
|
||||||
|
}DAC_InitTypeDef;
|
||||||
|
|
||||||
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
|
||||||
|
/** @defgroup DAC_Exported_Constants
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup DAC_trigger_selection
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DAC_Trigger_None ((uint32_t)0x00000000) /*!< Conversion is automatic once the DAC1_DHRxxxx register
|
||||||
|
has been loaded, and not by external trigger */
|
||||||
|
#define DAC_Trigger_T2_TRGO ((uint32_t)0x00000024) /*!< TIM2 TRGO selected as external conversion trigger for DAC channel */
|
||||||
|
#define DAC_Trigger_T4_TRGO ((uint32_t)0x0000002C) /*!< TIM4 TRGO selected as external conversion trigger for DAC channel */
|
||||||
|
#define DAC_Trigger_T5_TRGO ((uint32_t)0x0000001C) /*!< TIM5 TRGO selected as external conversion trigger for DAC channel */
|
||||||
|
#define DAC_Trigger_T6_TRGO ((uint32_t)0x00000004) /*!< TIM6 TRGO selected as external conversion trigger for DAC channel */
|
||||||
|
#define DAC_Trigger_T7_TRGO ((uint32_t)0x00000014) /*!< TIM7 TRGO selected as external conversion trigger for DAC channel */
|
||||||
|
#define DAC_Trigger_T8_TRGO ((uint32_t)0x0000000C) /*!< TIM8 TRGO selected as external conversion trigger for DAC channel */
|
||||||
|
|
||||||
|
#define DAC_Trigger_Ext_IT9 ((uint32_t)0x00000034) /*!< EXTI Line9 event selected as external conversion trigger for DAC channel */
|
||||||
|
#define DAC_Trigger_Software ((uint32_t)0x0000003C) /*!< Conversion started by software trigger for DAC channel */
|
||||||
|
|
||||||
|
#define IS_DAC_TRIGGER(TRIGGER) (((TRIGGER) == DAC_Trigger_None) || \
|
||||||
|
((TRIGGER) == DAC_Trigger_T6_TRGO) || \
|
||||||
|
((TRIGGER) == DAC_Trigger_T8_TRGO) || \
|
||||||
|
((TRIGGER) == DAC_Trigger_T7_TRGO) || \
|
||||||
|
((TRIGGER) == DAC_Trigger_T5_TRGO) || \
|
||||||
|
((TRIGGER) == DAC_Trigger_T2_TRGO) || \
|
||||||
|
((TRIGGER) == DAC_Trigger_T4_TRGO) || \
|
||||||
|
((TRIGGER) == DAC_Trigger_Ext_IT9) || \
|
||||||
|
((TRIGGER) == DAC_Trigger_Software))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup DAC_wave_generation
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DAC_WaveGeneration_None ((uint32_t)0x00000000)
|
||||||
|
#define DAC_WaveGeneration_Noise ((uint32_t)0x00000040)
|
||||||
|
#define DAC_WaveGeneration_Triangle ((uint32_t)0x00000080)
|
||||||
|
#define IS_DAC_GENERATE_WAVE(WAVE) (((WAVE) == DAC_WaveGeneration_None) || \
|
||||||
|
((WAVE) == DAC_WaveGeneration_Noise) || \
|
||||||
|
((WAVE) == DAC_WaveGeneration_Triangle))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup DAC_lfsrunmask_triangleamplitude
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DAC_LFSRUnmask_Bit0 ((uint32_t)0x00000000) /*!< Unmask DAC channel LFSR bit0 for noise wave generation */
|
||||||
|
#define DAC_LFSRUnmask_Bits1_0 ((uint32_t)0x00000100) /*!< Unmask DAC channel LFSR bit[1:0] for noise wave generation */
|
||||||
|
#define DAC_LFSRUnmask_Bits2_0 ((uint32_t)0x00000200) /*!< Unmask DAC channel LFSR bit[2:0] for noise wave generation */
|
||||||
|
#define DAC_LFSRUnmask_Bits3_0 ((uint32_t)0x00000300) /*!< Unmask DAC channel LFSR bit[3:0] for noise wave generation */
|
||||||
|
#define DAC_LFSRUnmask_Bits4_0 ((uint32_t)0x00000400) /*!< Unmask DAC channel LFSR bit[4:0] for noise wave generation */
|
||||||
|
#define DAC_LFSRUnmask_Bits5_0 ((uint32_t)0x00000500) /*!< Unmask DAC channel LFSR bit[5:0] for noise wave generation */
|
||||||
|
#define DAC_LFSRUnmask_Bits6_0 ((uint32_t)0x00000600) /*!< Unmask DAC channel LFSR bit[6:0] for noise wave generation */
|
||||||
|
#define DAC_LFSRUnmask_Bits7_0 ((uint32_t)0x00000700) /*!< Unmask DAC channel LFSR bit[7:0] for noise wave generation */
|
||||||
|
#define DAC_LFSRUnmask_Bits8_0 ((uint32_t)0x00000800) /*!< Unmask DAC channel LFSR bit[8:0] for noise wave generation */
|
||||||
|
#define DAC_LFSRUnmask_Bits9_0 ((uint32_t)0x00000900) /*!< Unmask DAC channel LFSR bit[9:0] for noise wave generation */
|
||||||
|
#define DAC_LFSRUnmask_Bits10_0 ((uint32_t)0x00000A00) /*!< Unmask DAC channel LFSR bit[10:0] for noise wave generation */
|
||||||
|
#define DAC_LFSRUnmask_Bits11_0 ((uint32_t)0x00000B00) /*!< Unmask DAC channel LFSR bit[11:0] for noise wave generation */
|
||||||
|
#define DAC_TriangleAmplitude_1 ((uint32_t)0x00000000) /*!< Select max triangle amplitude of 1 */
|
||||||
|
#define DAC_TriangleAmplitude_3 ((uint32_t)0x00000100) /*!< Select max triangle amplitude of 3 */
|
||||||
|
#define DAC_TriangleAmplitude_7 ((uint32_t)0x00000200) /*!< Select max triangle amplitude of 7 */
|
||||||
|
#define DAC_TriangleAmplitude_15 ((uint32_t)0x00000300) /*!< Select max triangle amplitude of 15 */
|
||||||
|
#define DAC_TriangleAmplitude_31 ((uint32_t)0x00000400) /*!< Select max triangle amplitude of 31 */
|
||||||
|
#define DAC_TriangleAmplitude_63 ((uint32_t)0x00000500) /*!< Select max triangle amplitude of 63 */
|
||||||
|
#define DAC_TriangleAmplitude_127 ((uint32_t)0x00000600) /*!< Select max triangle amplitude of 127 */
|
||||||
|
#define DAC_TriangleAmplitude_255 ((uint32_t)0x00000700) /*!< Select max triangle amplitude of 255 */
|
||||||
|
#define DAC_TriangleAmplitude_511 ((uint32_t)0x00000800) /*!< Select max triangle amplitude of 511 */
|
||||||
|
#define DAC_TriangleAmplitude_1023 ((uint32_t)0x00000900) /*!< Select max triangle amplitude of 1023 */
|
||||||
|
#define DAC_TriangleAmplitude_2047 ((uint32_t)0x00000A00) /*!< Select max triangle amplitude of 2047 */
|
||||||
|
#define DAC_TriangleAmplitude_4095 ((uint32_t)0x00000B00) /*!< Select max triangle amplitude of 4095 */
|
||||||
|
|
||||||
|
#define IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(VALUE) (((VALUE) == DAC_LFSRUnmask_Bit0) || \
|
||||||
|
((VALUE) == DAC_LFSRUnmask_Bits1_0) || \
|
||||||
|
((VALUE) == DAC_LFSRUnmask_Bits2_0) || \
|
||||||
|
((VALUE) == DAC_LFSRUnmask_Bits3_0) || \
|
||||||
|
((VALUE) == DAC_LFSRUnmask_Bits4_0) || \
|
||||||
|
((VALUE) == DAC_LFSRUnmask_Bits5_0) || \
|
||||||
|
((VALUE) == DAC_LFSRUnmask_Bits6_0) || \
|
||||||
|
((VALUE) == DAC_LFSRUnmask_Bits7_0) || \
|
||||||
|
((VALUE) == DAC_LFSRUnmask_Bits8_0) || \
|
||||||
|
((VALUE) == DAC_LFSRUnmask_Bits9_0) || \
|
||||||
|
((VALUE) == DAC_LFSRUnmask_Bits10_0) || \
|
||||||
|
((VALUE) == DAC_LFSRUnmask_Bits11_0) || \
|
||||||
|
((VALUE) == DAC_TriangleAmplitude_1) || \
|
||||||
|
((VALUE) == DAC_TriangleAmplitude_3) || \
|
||||||
|
((VALUE) == DAC_TriangleAmplitude_7) || \
|
||||||
|
((VALUE) == DAC_TriangleAmplitude_15) || \
|
||||||
|
((VALUE) == DAC_TriangleAmplitude_31) || \
|
||||||
|
((VALUE) == DAC_TriangleAmplitude_63) || \
|
||||||
|
((VALUE) == DAC_TriangleAmplitude_127) || \
|
||||||
|
((VALUE) == DAC_TriangleAmplitude_255) || \
|
||||||
|
((VALUE) == DAC_TriangleAmplitude_511) || \
|
||||||
|
((VALUE) == DAC_TriangleAmplitude_1023) || \
|
||||||
|
((VALUE) == DAC_TriangleAmplitude_2047) || \
|
||||||
|
((VALUE) == DAC_TriangleAmplitude_4095))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup DAC_output_buffer
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DAC_OutputBuffer_Enable ((uint32_t)0x00000000)
|
||||||
|
#define DAC_OutputBuffer_Disable ((uint32_t)0x00000002)
|
||||||
|
#define IS_DAC_OUTPUT_BUFFER_STATE(STATE) (((STATE) == DAC_OutputBuffer_Enable) || \
|
||||||
|
((STATE) == DAC_OutputBuffer_Disable))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup DAC_Channel_selection
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DAC_Channel_1 ((uint32_t)0x00000000)
|
||||||
|
#define DAC_Channel_2 ((uint32_t)0x00000010)
|
||||||
|
#define IS_DAC_CHANNEL(CHANNEL) (((CHANNEL) == DAC_Channel_1) || \
|
||||||
|
((CHANNEL) == DAC_Channel_2))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup DAC_data_alignement
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DAC_Align_12b_R ((uint32_t)0x00000000)
|
||||||
|
#define DAC_Align_12b_L ((uint32_t)0x00000004)
|
||||||
|
#define DAC_Align_8b_R ((uint32_t)0x00000008)
|
||||||
|
#define IS_DAC_ALIGN(ALIGN) (((ALIGN) == DAC_Align_12b_R) || \
|
||||||
|
((ALIGN) == DAC_Align_12b_L) || \
|
||||||
|
((ALIGN) == DAC_Align_8b_R))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup DAC_wave_generation
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DAC_Wave_Noise ((uint32_t)0x00000040)
|
||||||
|
#define DAC_Wave_Triangle ((uint32_t)0x00000080)
|
||||||
|
#define IS_DAC_WAVE(WAVE) (((WAVE) == DAC_Wave_Noise) || \
|
||||||
|
((WAVE) == DAC_Wave_Triangle))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup DAC_data
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define IS_DAC_DATA(DATA) ((DATA) <= 0xFFF0)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup DAC_interrupts_definition
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define DAC_IT_DMAUDR ((uint32_t)0x00002000)
|
||||||
|
#define IS_DAC_IT(IT) (((IT) == DAC_IT_DMAUDR))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup DAC_flags_definition
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DAC_FLAG_DMAUDR ((uint32_t)0x00002000)
|
||||||
|
#define IS_DAC_FLAG(FLAG) (((FLAG) == DAC_FLAG_DMAUDR))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Function used to set the DAC configuration to the default reset state *****/
|
||||||
|
void DAC_DeInit(void);
|
||||||
|
|
||||||
|
/* DAC channels configuration: trigger, output buffer, data format functions */
|
||||||
|
void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct);
|
||||||
|
void DAC_StructInit(DAC_InitTypeDef* DAC_InitStruct);
|
||||||
|
void DAC_Cmd(uint32_t DAC_Channel, FunctionalState NewState);
|
||||||
|
void DAC_SoftwareTriggerCmd(uint32_t DAC_Channel, FunctionalState NewState);
|
||||||
|
void DAC_DualSoftwareTriggerCmd(FunctionalState NewState);
|
||||||
|
void DAC_WaveGenerationCmd(uint32_t DAC_Channel, uint32_t DAC_Wave, FunctionalState NewState);
|
||||||
|
void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data);
|
||||||
|
void DAC_SetChannel2Data(uint32_t DAC_Align, uint16_t Data);
|
||||||
|
void DAC_SetDualChannelData(uint32_t DAC_Align, uint16_t Data2, uint16_t Data1);
|
||||||
|
uint16_t DAC_GetDataOutputValue(uint32_t DAC_Channel);
|
||||||
|
|
||||||
|
/* DMA management functions ***************************************************/
|
||||||
|
void DAC_DMACmd(uint32_t DAC_Channel, FunctionalState NewState);
|
||||||
|
|
||||||
|
/* Interrupts and flags management functions **********************************/
|
||||||
|
void DAC_ITConfig(uint32_t DAC_Channel, uint32_t DAC_IT, FunctionalState NewState);
|
||||||
|
FlagStatus DAC_GetFlagStatus(uint32_t DAC_Channel, uint32_t DAC_FLAG);
|
||||||
|
void DAC_ClearFlag(uint32_t DAC_Channel, uint32_t DAC_FLAG);
|
||||||
|
ITStatus DAC_GetITStatus(uint32_t DAC_Channel, uint32_t DAC_IT);
|
||||||
|
void DAC_ClearITPendingBit(uint32_t DAC_Channel, uint32_t DAC_IT);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*__STM32F4xx_DAC_H */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
@@ -0,0 +1,564 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f4xx_gpio.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @version V1.7.1
|
||||||
|
* @date 20-May-2016
|
||||||
|
* @brief This file contains all the functions prototypes for the GPIO firmware
|
||||||
|
* library.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
|
||||||
|
*
|
||||||
|
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.st.com/software_license_agreement_liberty_v2
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __STM32F4xx_GPIO_H
|
||||||
|
#define __STM32F4xx_GPIO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32F4xx_StdPeriph_Driver
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup GPIO
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \
|
||||||
|
((PERIPH) == GPIOB) || \
|
||||||
|
((PERIPH) == GPIOC) || \
|
||||||
|
((PERIPH) == GPIOD) || \
|
||||||
|
((PERIPH) == GPIOE) || \
|
||||||
|
((PERIPH) == GPIOF) || \
|
||||||
|
((PERIPH) == GPIOG) || \
|
||||||
|
((PERIPH) == GPIOH) || \
|
||||||
|
((PERIPH) == GPIOI) || \
|
||||||
|
((PERIPH) == GPIOJ) || \
|
||||||
|
((PERIPH) == GPIOK))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GPIO Configuration Mode enumeration
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */
|
||||||
|
GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */
|
||||||
|
GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */
|
||||||
|
GPIO_Mode_AN = 0x03 /*!< GPIO Analog Mode */
|
||||||
|
}GPIOMode_TypeDef;
|
||||||
|
#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_IN) || ((MODE) == GPIO_Mode_OUT) || \
|
||||||
|
((MODE) == GPIO_Mode_AF)|| ((MODE) == GPIO_Mode_AN))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GPIO Output type enumeration
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GPIO_OType_PP = 0x00,
|
||||||
|
GPIO_OType_OD = 0x01
|
||||||
|
}GPIOOType_TypeDef;
|
||||||
|
#define IS_GPIO_OTYPE(OTYPE) (((OTYPE) == GPIO_OType_PP) || ((OTYPE) == GPIO_OType_OD))
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GPIO Output Maximum frequency enumeration
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GPIO_Low_Speed = 0x00, /*!< Low speed */
|
||||||
|
GPIO_Medium_Speed = 0x01, /*!< Medium speed */
|
||||||
|
GPIO_Fast_Speed = 0x02, /*!< Fast speed */
|
||||||
|
GPIO_High_Speed = 0x03 /*!< High speed */
|
||||||
|
}GPIOSpeed_TypeDef;
|
||||||
|
|
||||||
|
/* Add legacy definition */
|
||||||
|
#define GPIO_Speed_2MHz GPIO_Low_Speed
|
||||||
|
#define GPIO_Speed_25MHz GPIO_Medium_Speed
|
||||||
|
#define GPIO_Speed_50MHz GPIO_Fast_Speed
|
||||||
|
#define GPIO_Speed_100MHz GPIO_High_Speed
|
||||||
|
|
||||||
|
#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Low_Speed) || ((SPEED) == GPIO_Medium_Speed) || \
|
||||||
|
((SPEED) == GPIO_Fast_Speed)|| ((SPEED) == GPIO_High_Speed))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GPIO Configuration PullUp PullDown enumeration
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GPIO_PuPd_NOPULL = 0x00,
|
||||||
|
GPIO_PuPd_UP = 0x01,
|
||||||
|
GPIO_PuPd_DOWN = 0x02
|
||||||
|
}GPIOPuPd_TypeDef;
|
||||||
|
#define IS_GPIO_PUPD(PUPD) (((PUPD) == GPIO_PuPd_NOPULL) || ((PUPD) == GPIO_PuPd_UP) || \
|
||||||
|
((PUPD) == GPIO_PuPd_DOWN))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GPIO Bit SET and Bit RESET enumeration
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
Bit_RESET = 0,
|
||||||
|
Bit_SET
|
||||||
|
}BitAction;
|
||||||
|
#define IS_GPIO_BIT_ACTION(ACTION) (((ACTION) == Bit_RESET) || ((ACTION) == Bit_SET))
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GPIO Init structure definition
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured.
|
||||||
|
This parameter can be any value of @ref GPIO_pins_define */
|
||||||
|
|
||||||
|
GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins.
|
||||||
|
This parameter can be a value of @ref GPIOMode_TypeDef */
|
||||||
|
|
||||||
|
GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins.
|
||||||
|
This parameter can be a value of @ref GPIOSpeed_TypeDef */
|
||||||
|
|
||||||
|
GPIOOType_TypeDef GPIO_OType; /*!< Specifies the operating output type for the selected pins.
|
||||||
|
This parameter can be a value of @ref GPIOOType_TypeDef */
|
||||||
|
|
||||||
|
GPIOPuPd_TypeDef GPIO_PuPd; /*!< Specifies the operating Pull-up/Pull down for the selected pins.
|
||||||
|
This parameter can be a value of @ref GPIOPuPd_TypeDef */
|
||||||
|
}GPIO_InitTypeDef;
|
||||||
|
|
||||||
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
|
||||||
|
/** @defgroup GPIO_Exported_Constants
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup GPIO_pins_define
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define GPIO_Pin_0 ((uint16_t)0x0001) /* Pin 0 selected */
|
||||||
|
#define GPIO_Pin_1 ((uint16_t)0x0002) /* Pin 1 selected */
|
||||||
|
#define GPIO_Pin_2 ((uint16_t)0x0004) /* Pin 2 selected */
|
||||||
|
#define GPIO_Pin_3 ((uint16_t)0x0008) /* Pin 3 selected */
|
||||||
|
#define GPIO_Pin_4 ((uint16_t)0x0010) /* Pin 4 selected */
|
||||||
|
#define GPIO_Pin_5 ((uint16_t)0x0020) /* Pin 5 selected */
|
||||||
|
#define GPIO_Pin_6 ((uint16_t)0x0040) /* Pin 6 selected */
|
||||||
|
#define GPIO_Pin_7 ((uint16_t)0x0080) /* Pin 7 selected */
|
||||||
|
#define GPIO_Pin_8 ((uint16_t)0x0100) /* Pin 8 selected */
|
||||||
|
#define GPIO_Pin_9 ((uint16_t)0x0200) /* Pin 9 selected */
|
||||||
|
#define GPIO_Pin_10 ((uint16_t)0x0400) /* Pin 10 selected */
|
||||||
|
#define GPIO_Pin_11 ((uint16_t)0x0800) /* Pin 11 selected */
|
||||||
|
#define GPIO_Pin_12 ((uint16_t)0x1000) /* Pin 12 selected */
|
||||||
|
#define GPIO_Pin_13 ((uint16_t)0x2000) /* Pin 13 selected */
|
||||||
|
#define GPIO_Pin_14 ((uint16_t)0x4000) /* Pin 14 selected */
|
||||||
|
#define GPIO_Pin_15 ((uint16_t)0x8000) /* Pin 15 selected */
|
||||||
|
#define GPIO_Pin_All ((uint16_t)0xFFFF) /* All pins selected */
|
||||||
|
|
||||||
|
#define GPIO_PIN_MASK ((uint32_t)0x0000FFFF) /* PIN mask for assert test */
|
||||||
|
#define IS_GPIO_PIN(PIN) (((PIN) & GPIO_PIN_MASK ) != (uint32_t)0x00)
|
||||||
|
#define IS_GET_GPIO_PIN(PIN) (((PIN) == GPIO_Pin_0) || \
|
||||||
|
((PIN) == GPIO_Pin_1) || \
|
||||||
|
((PIN) == GPIO_Pin_2) || \
|
||||||
|
((PIN) == GPIO_Pin_3) || \
|
||||||
|
((PIN) == GPIO_Pin_4) || \
|
||||||
|
((PIN) == GPIO_Pin_5) || \
|
||||||
|
((PIN) == GPIO_Pin_6) || \
|
||||||
|
((PIN) == GPIO_Pin_7) || \
|
||||||
|
((PIN) == GPIO_Pin_8) || \
|
||||||
|
((PIN) == GPIO_Pin_9) || \
|
||||||
|
((PIN) == GPIO_Pin_10) || \
|
||||||
|
((PIN) == GPIO_Pin_11) || \
|
||||||
|
((PIN) == GPIO_Pin_12) || \
|
||||||
|
((PIN) == GPIO_Pin_13) || \
|
||||||
|
((PIN) == GPIO_Pin_14) || \
|
||||||
|
((PIN) == GPIO_Pin_15))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup GPIO_Pin_sources
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define GPIO_PinSource0 ((uint8_t)0x00)
|
||||||
|
#define GPIO_PinSource1 ((uint8_t)0x01)
|
||||||
|
#define GPIO_PinSource2 ((uint8_t)0x02)
|
||||||
|
#define GPIO_PinSource3 ((uint8_t)0x03)
|
||||||
|
#define GPIO_PinSource4 ((uint8_t)0x04)
|
||||||
|
#define GPIO_PinSource5 ((uint8_t)0x05)
|
||||||
|
#define GPIO_PinSource6 ((uint8_t)0x06)
|
||||||
|
#define GPIO_PinSource7 ((uint8_t)0x07)
|
||||||
|
#define GPIO_PinSource8 ((uint8_t)0x08)
|
||||||
|
#define GPIO_PinSource9 ((uint8_t)0x09)
|
||||||
|
#define GPIO_PinSource10 ((uint8_t)0x0A)
|
||||||
|
#define GPIO_PinSource11 ((uint8_t)0x0B)
|
||||||
|
#define GPIO_PinSource12 ((uint8_t)0x0C)
|
||||||
|
#define GPIO_PinSource13 ((uint8_t)0x0D)
|
||||||
|
#define GPIO_PinSource14 ((uint8_t)0x0E)
|
||||||
|
#define GPIO_PinSource15 ((uint8_t)0x0F)
|
||||||
|
|
||||||
|
#define IS_GPIO_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == GPIO_PinSource0) || \
|
||||||
|
((PINSOURCE) == GPIO_PinSource1) || \
|
||||||
|
((PINSOURCE) == GPIO_PinSource2) || \
|
||||||
|
((PINSOURCE) == GPIO_PinSource3) || \
|
||||||
|
((PINSOURCE) == GPIO_PinSource4) || \
|
||||||
|
((PINSOURCE) == GPIO_PinSource5) || \
|
||||||
|
((PINSOURCE) == GPIO_PinSource6) || \
|
||||||
|
((PINSOURCE) == GPIO_PinSource7) || \
|
||||||
|
((PINSOURCE) == GPIO_PinSource8) || \
|
||||||
|
((PINSOURCE) == GPIO_PinSource9) || \
|
||||||
|
((PINSOURCE) == GPIO_PinSource10) || \
|
||||||
|
((PINSOURCE) == GPIO_PinSource11) || \
|
||||||
|
((PINSOURCE) == GPIO_PinSource12) || \
|
||||||
|
((PINSOURCE) == GPIO_PinSource13) || \
|
||||||
|
((PINSOURCE) == GPIO_PinSource14) || \
|
||||||
|
((PINSOURCE) == GPIO_PinSource15))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup GPIO_Alternat_function_selection_define
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @brief AF 0 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF_RTC_50Hz ((uint8_t)0x00) /* RTC_50Hz Alternate Function mapping */
|
||||||
|
#define GPIO_AF_MCO ((uint8_t)0x00) /* MCO (MCO1 and MCO2) Alternate Function mapping */
|
||||||
|
#define GPIO_AF_TAMPER ((uint8_t)0x00) /* TAMPER (TAMPER_1 and TAMPER_2) Alternate Function mapping */
|
||||||
|
#define GPIO_AF_SWJ ((uint8_t)0x00) /* SWJ (SWD and JTAG) Alternate Function mapping */
|
||||||
|
#define GPIO_AF_TRACE ((uint8_t)0x00) /* TRACE Alternate Function mapping */
|
||||||
|
#if defined(STM32F446xx)
|
||||||
|
#define GPIO_AF0_TIM2 ((uint8_t)0x00) /* TIM2 Alternate Function mapping */
|
||||||
|
#endif /* STM32F446xx */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 1 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF_TIM1 ((uint8_t)0x01) /* TIM1 Alternate Function mapping */
|
||||||
|
#define GPIO_AF_TIM2 ((uint8_t)0x01) /* TIM2 Alternate Function mapping */
|
||||||
|
#if defined(STM32F410xx)
|
||||||
|
#define GPIO_AF_LPTIM ((uint8_t)0x01) /* LPTIM Alternate Function mapping */
|
||||||
|
#endif /* STM32F410xx */
|
||||||
|
/**
|
||||||
|
* @brief AF 2 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF_TIM3 ((uint8_t)0x02) /* TIM3 Alternate Function mapping */
|
||||||
|
#define GPIO_AF_TIM4 ((uint8_t)0x02) /* TIM4 Alternate Function mapping */
|
||||||
|
#define GPIO_AF_TIM5 ((uint8_t)0x02) /* TIM5 Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 3 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF_TIM8 ((uint8_t)0x03) /* TIM8 Alternate Function mapping */
|
||||||
|
#define GPIO_AF_TIM9 ((uint8_t)0x03) /* TIM9 Alternate Function mapping */
|
||||||
|
#define GPIO_AF_TIM10 ((uint8_t)0x03) /* TIM10 Alternate Function mapping */
|
||||||
|
#define GPIO_AF_TIM11 ((uint8_t)0x03) /* TIM11 Alternate Function mapping */
|
||||||
|
#if defined(STM32F446xx)
|
||||||
|
#define GPIO_AF3_CEC ((uint8_t)0x03) /* CEC Alternate Function mapping */
|
||||||
|
#endif /* STM32F446xx */
|
||||||
|
/**
|
||||||
|
* @brief AF 4 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF_I2C1 ((uint8_t)0x04) /* I2C1 Alternate Function mapping */
|
||||||
|
#define GPIO_AF_I2C2 ((uint8_t)0x04) /* I2C2 Alternate Function mapping */
|
||||||
|
#define GPIO_AF_I2C3 ((uint8_t)0x04) /* I2C3 Alternate Function mapping */
|
||||||
|
#if defined(STM32F446xx)
|
||||||
|
#define GPIO_AF4_CEC ((uint8_t)0x04) /* CEC Alternate Function mapping */
|
||||||
|
#endif /* STM32F446xx */
|
||||||
|
#if defined(STM32F410xx) || defined(STM32F412xG) || defined(STM32F446xx)
|
||||||
|
#define GPIO_AF_FMPI2C ((uint8_t)0x04) /* FMPI2C Alternate Function mapping */
|
||||||
|
#endif /* STM32F410xx || STM32F446xx */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 5 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF_SPI1 ((uint8_t)0x05) /* SPI1/I2S1 Alternate Function mapping */
|
||||||
|
#define GPIO_AF_SPI2 ((uint8_t)0x05) /* SPI2/I2S2 Alternate Function mapping */
|
||||||
|
#define GPIO_AF5_SPI3 ((uint8_t)0x05) /* SPI3/I2S3 Alternate Function mapping (Only for STM32F411xE Devices) */
|
||||||
|
#define GPIO_AF_SPI4 ((uint8_t)0x05) /* SPI4/I2S4 Alternate Function mapping */
|
||||||
|
#define GPIO_AF_SPI5 ((uint8_t)0x05) /* SPI5 Alternate Function mapping */
|
||||||
|
#define GPIO_AF_SPI6 ((uint8_t)0x05) /* SPI6 Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 6 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF_SPI3 ((uint8_t)0x06) /* SPI3/I2S3 Alternate Function mapping */
|
||||||
|
#define GPIO_AF6_SPI1 ((uint8_t)0x06) /* SPI1 Alternate Function mapping (Only for STM32F410xx Devices) */
|
||||||
|
#define GPIO_AF6_SPI2 ((uint8_t)0x06) /* SPI2 Alternate Function mapping (Only for STM32F410xx/STM32F411xE Devices) */
|
||||||
|
#define GPIO_AF6_SPI4 ((uint8_t)0x06) /* SPI4 Alternate Function mapping (Only for STM32F411xE Devices) */
|
||||||
|
#define GPIO_AF6_SPI5 ((uint8_t)0x06) /* SPI5 Alternate Function mapping (Only for STM32F410xx/STM32F411xE Devices) */
|
||||||
|
#define GPIO_AF_SAI1 ((uint8_t)0x06) /* SAI1 Alternate Function mapping */
|
||||||
|
#define GPIO_AF_I2S2ext ((uint8_t)0x06) /* I2S2ext_SD Alternate Function mapping (only for STM32F412xG Devices) */
|
||||||
|
#if defined(STM32F412xG)
|
||||||
|
#define GPIO_AF6_DFSDM1 ((uint8_t)0x06) /* DFSDM Alternate Function mapping */
|
||||||
|
#endif /* STM32F412xG */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 7 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF_USART1 ((uint8_t)0x07) /* USART1 Alternate Function mapping */
|
||||||
|
#define GPIO_AF_USART2 ((uint8_t)0x07) /* USART2 Alternate Function mapping */
|
||||||
|
#define GPIO_AF_USART3 ((uint8_t)0x07) /* USART3 Alternate Function mapping */
|
||||||
|
#define GPIO_AF7_SPI3 ((uint8_t)0x07) /* SPI3/I2S3ext Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 7 selection Legacy
|
||||||
|
*/
|
||||||
|
#define GPIO_AF_I2S3ext GPIO_AF7_SPI3
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 8 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF_UART4 ((uint8_t)0x08) /* UART4 Alternate Function mapping */
|
||||||
|
#define GPIO_AF_UART5 ((uint8_t)0x08) /* UART5 Alternate Function mapping */
|
||||||
|
#define GPIO_AF_USART6 ((uint8_t)0x08) /* USART6 Alternate Function mapping */
|
||||||
|
#define GPIO_AF_UART7 ((uint8_t)0x08) /* UART7 Alternate Function mapping */
|
||||||
|
#define GPIO_AF_UART8 ((uint8_t)0x08) /* UART8 Alternate Function mapping */
|
||||||
|
#if defined(STM32F412xG)
|
||||||
|
#define GPIO_AF8_USART3 ((uint8_t)0x08) /* USART3 Alternate Function mapping */
|
||||||
|
#define GPIO_AF8_DFSDM1 ((uint8_t)0x08) /* DFSDM Alternate Function mapping */
|
||||||
|
#define GPIO_AF8_CAN1 ((uint8_t)0x08) /* CAN1 Alternate Function mapping */
|
||||||
|
#endif /* STM32F412xG */
|
||||||
|
#if defined(STM32F446xx)
|
||||||
|
#define GPIO_AF8_SAI2 ((uint8_t)0x08) /* SAI2 Alternate Function mapping */
|
||||||
|
#define GPIO_AF_SPDIF ((uint8_t)0x08) /* SPDIF Alternate Function mapping */
|
||||||
|
#endif /* STM32F446xx */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 9 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF_CAN1 ((uint8_t)0x09) /* CAN1 Alternate Function mapping */
|
||||||
|
#define GPIO_AF_CAN2 ((uint8_t)0x09) /* CAN2 Alternate Function mapping */
|
||||||
|
#define GPIO_AF_TIM12 ((uint8_t)0x09) /* TIM12 Alternate Function mapping */
|
||||||
|
#define GPIO_AF_TIM13 ((uint8_t)0x09) /* TIM13 Alternate Function mapping */
|
||||||
|
#define GPIO_AF_TIM14 ((uint8_t)0x09) /* TIM14 Alternate Function mapping */
|
||||||
|
#define GPIO_AF9_I2C2 ((uint8_t)0x09) /* I2C2 Alternate Function mapping (Only for STM32F401xx/STM32F410xx/STM32F411xE/STM32F412xG Devices) */
|
||||||
|
#define GPIO_AF9_I2C3 ((uint8_t)0x09) /* I2C3 Alternate Function mapping (Only for STM32F401xx/STM32F411xE/STM32F412xG Devices) */
|
||||||
|
#if defined(STM32F446xx)
|
||||||
|
#define GPIO_AF9_SAI2 ((uint8_t)0x09) /* SAI2 Alternate Function mapping */
|
||||||
|
#endif /* STM32F446xx */
|
||||||
|
#define GPIO_AF9_LTDC ((uint8_t)0x09) /* LTDC Alternate Function mapping */
|
||||||
|
#if defined(STM32F412xG) || defined(STM32F446xx) || defined(STM32F469_479xx)
|
||||||
|
#define GPIO_AF9_QUADSPI ((uint8_t)0x09) /* QuadSPI Alternate Function mapping */
|
||||||
|
#endif /* STM32F412xG || STM32F446xx || STM32F469_479xx */
|
||||||
|
#if defined(STM32F410xx) || defined(STM32F412xG)
|
||||||
|
#define GPIO_AF9_FMPI2C ((uint8_t)0x09) /* FMPI2C Alternate Function mapping (Only for STM32F410xx Devices) */
|
||||||
|
#endif /* STM32F410xx || STM32F412xG */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 10 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF_OTG_FS ((uint8_t)0xA) /* OTG_FS Alternate Function mapping */
|
||||||
|
#define GPIO_AF_OTG_HS ((uint8_t)0xA) /* OTG_HS Alternate Function mapping */
|
||||||
|
#if defined(STM32F446xx)
|
||||||
|
#define GPIO_AF10_SAI2 ((uint8_t)0x0A) /* SAI2 Alternate Function mapping */
|
||||||
|
#endif /* STM32F446xx */
|
||||||
|
#if defined(STM32F412xG) || defined(STM32F446xx) || defined(STM32F469_479xx)
|
||||||
|
#define GPIO_AF10_QUADSPI ((uint8_t)0x0A) /* QuadSPI Alternate Function mapping */
|
||||||
|
#endif /* STM32F412xG || STM32F446xx || STM32F469_479xx */
|
||||||
|
#if defined(STM32F412xG)
|
||||||
|
#define GPIO_AF10_FMC ((uint8_t)0xA) /* FMC Alternate Function mapping */
|
||||||
|
#define GPIO_AF10_DFSDM ((uint8_t)0xA) /* DFSDM Alternate Function mapping */
|
||||||
|
#endif /* STM32F412xG */
|
||||||
|
/**
|
||||||
|
* @brief AF 11 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF_ETH ((uint8_t)0x0B) /* ETHERNET Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 12 selection
|
||||||
|
*/
|
||||||
|
#if defined(STM32F40_41xxx) || defined(STM32F412xG)
|
||||||
|
#define GPIO_AF_FSMC ((uint8_t)0xC) /* FSMC Alternate Function mapping */
|
||||||
|
#endif /* STM32F40_41xxx || STM32F412xG */
|
||||||
|
|
||||||
|
#if defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F446xx) || defined(STM32F469_479xx)
|
||||||
|
#define GPIO_AF_FMC ((uint8_t)0xC) /* FMC Alternate Function mapping */
|
||||||
|
#endif /* STM32F427_437xx || STM32F429_439xx || STM32F446xx || STM32F469_479xx */
|
||||||
|
|
||||||
|
#define GPIO_AF_OTG_HS_FS ((uint8_t)0xC) /* OTG HS configured in FS, Alternate Function mapping */
|
||||||
|
#define GPIO_AF_SDIO ((uint8_t)0xC) /* SDIO Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 13 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF_DCMI ((uint8_t)0x0D) /* DCMI Alternate Function mapping */
|
||||||
|
#if defined(STM32F469_479xx)
|
||||||
|
#define GPIO_AF_DSI ((uint8_t)0x0D) /* DSI Alternate Function mapping */
|
||||||
|
#endif /* STM32F469_479xx */
|
||||||
|
/**
|
||||||
|
* @brief AF 14 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF_LTDC ((uint8_t)0x0E) /* LCD-TFT Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 15 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF_EVENTOUT ((uint8_t)0x0F) /* EVENTOUT Alternate Function mapping */
|
||||||
|
|
||||||
|
#if defined(STM32F40_41xxx)
|
||||||
|
#define IS_GPIO_AF(AF) (((AF) == GPIO_AF_RTC_50Hz) || ((AF) == GPIO_AF_TIM14) || \
|
||||||
|
((AF) == GPIO_AF_MCO) || ((AF) == GPIO_AF_TAMPER) || \
|
||||||
|
((AF) == GPIO_AF_SWJ) || ((AF) == GPIO_AF_TRACE) || \
|
||||||
|
((AF) == GPIO_AF_TIM1) || ((AF) == GPIO_AF_TIM2) || \
|
||||||
|
((AF) == GPIO_AF_TIM3) || ((AF) == GPIO_AF_TIM4) || \
|
||||||
|
((AF) == GPIO_AF_TIM5) || ((AF) == GPIO_AF_TIM8) || \
|
||||||
|
((AF) == GPIO_AF_I2C1) || ((AF) == GPIO_AF_I2C2) || \
|
||||||
|
((AF) == GPIO_AF_I2C3) || ((AF) == GPIO_AF_SPI1) || \
|
||||||
|
((AF) == GPIO_AF_SPI2) || ((AF) == GPIO_AF_TIM13) || \
|
||||||
|
((AF) == GPIO_AF_SPI3) || ((AF) == GPIO_AF_TIM14) || \
|
||||||
|
((AF) == GPIO_AF_USART1) || ((AF) == GPIO_AF_USART2) || \
|
||||||
|
((AF) == GPIO_AF_USART3) || ((AF) == GPIO_AF_UART4) || \
|
||||||
|
((AF) == GPIO_AF_UART5) || ((AF) == GPIO_AF_USART6) || \
|
||||||
|
((AF) == GPIO_AF_CAN1) || ((AF) == GPIO_AF_CAN2) || \
|
||||||
|
((AF) == GPIO_AF_OTG_FS) || ((AF) == GPIO_AF_OTG_HS) || \
|
||||||
|
((AF) == GPIO_AF_ETH) || ((AF) == GPIO_AF_OTG_HS_FS) || \
|
||||||
|
((AF) == GPIO_AF_SDIO) || ((AF) == GPIO_AF_DCMI) || \
|
||||||
|
((AF) == GPIO_AF_EVENTOUT) || ((AF) == GPIO_AF_FSMC))
|
||||||
|
#endif /* STM32F40_41xxx */
|
||||||
|
|
||||||
|
#if defined(STM32F401xx)
|
||||||
|
#define IS_GPIO_AF(AF) (((AF) == GPIO_AF_RTC_50Hz) || ((AF) == GPIO_AF_TIM14) || \
|
||||||
|
((AF) == GPIO_AF_MCO) || ((AF) == GPIO_AF_TAMPER) || \
|
||||||
|
((AF) == GPIO_AF_SWJ) || ((AF) == GPIO_AF_TRACE) || \
|
||||||
|
((AF) == GPIO_AF_TIM1) || ((AF) == GPIO_AF_TIM2) || \
|
||||||
|
((AF) == GPIO_AF_TIM3) || ((AF) == GPIO_AF_TIM4) || \
|
||||||
|
((AF) == GPIO_AF_TIM5) || ((AF) == GPIO_AF_TIM8) || \
|
||||||
|
((AF) == GPIO_AF_I2C1) || ((AF) == GPIO_AF_I2C2) || \
|
||||||
|
((AF) == GPIO_AF_I2C3) || ((AF) == GPIO_AF_SPI1) || \
|
||||||
|
((AF) == GPIO_AF_SPI2) || ((AF) == GPIO_AF_TIM13) || \
|
||||||
|
((AF) == GPIO_AF_SPI3) || ((AF) == GPIO_AF_TIM14) || \
|
||||||
|
((AF) == GPIO_AF_USART1) || ((AF) == GPIO_AF_USART2) || \
|
||||||
|
((AF) == GPIO_AF_SDIO) || ((AF) == GPIO_AF_USART6) || \
|
||||||
|
((AF) == GPIO_AF_OTG_FS) || ((AF) == GPIO_AF_OTG_HS) || \
|
||||||
|
((AF) == GPIO_AF_EVENTOUT) || ((AF) == GPIO_AF_SPI4))
|
||||||
|
#endif /* STM32F401xx */
|
||||||
|
|
||||||
|
#if defined(STM32F411xE)
|
||||||
|
#define IS_GPIO_AF(AF) (((AF) < 16) && ((AF) != 11) && ((AF) != 13) && ((AF) != 14))
|
||||||
|
#endif /* STM32F411xE */
|
||||||
|
|
||||||
|
#if defined(STM32F410xx)
|
||||||
|
#define IS_GPIO_AF(AF) (((AF) < 10) || ((AF) == 15))
|
||||||
|
#endif /* STM32F410xx */
|
||||||
|
|
||||||
|
#if defined(STM32F427_437xx) || defined(STM32F429_439xx)
|
||||||
|
#define IS_GPIO_AF(AF) (((AF) == GPIO_AF_RTC_50Hz) || ((AF) == GPIO_AF_TIM14) || \
|
||||||
|
((AF) == GPIO_AF_MCO) || ((AF) == GPIO_AF_TAMPER) || \
|
||||||
|
((AF) == GPIO_AF_SWJ) || ((AF) == GPIO_AF_TRACE) || \
|
||||||
|
((AF) == GPIO_AF_TIM1) || ((AF) == GPIO_AF_TIM2) || \
|
||||||
|
((AF) == GPIO_AF_TIM3) || ((AF) == GPIO_AF_TIM4) || \
|
||||||
|
((AF) == GPIO_AF_TIM5) || ((AF) == GPIO_AF_TIM8) || \
|
||||||
|
((AF) == GPIO_AF_I2C1) || ((AF) == GPIO_AF_I2C2) || \
|
||||||
|
((AF) == GPIO_AF_I2C3) || ((AF) == GPIO_AF_SPI1) || \
|
||||||
|
((AF) == GPIO_AF_SPI2) || ((AF) == GPIO_AF_TIM13) || \
|
||||||
|
((AF) == GPIO_AF_SPI3) || ((AF) == GPIO_AF_TIM14) || \
|
||||||
|
((AF) == GPIO_AF_USART1) || ((AF) == GPIO_AF_USART2) || \
|
||||||
|
((AF) == GPIO_AF_USART3) || ((AF) == GPIO_AF_UART4) || \
|
||||||
|
((AF) == GPIO_AF_UART5) || ((AF) == GPIO_AF_USART6) || \
|
||||||
|
((AF) == GPIO_AF_CAN1) || ((AF) == GPIO_AF_CAN2) || \
|
||||||
|
((AF) == GPIO_AF_OTG_FS) || ((AF) == GPIO_AF_OTG_HS) || \
|
||||||
|
((AF) == GPIO_AF_ETH) || ((AF) == GPIO_AF_OTG_HS_FS) || \
|
||||||
|
((AF) == GPIO_AF_SDIO) || ((AF) == GPIO_AF_DCMI) || \
|
||||||
|
((AF) == GPIO_AF_EVENTOUT) || ((AF) == GPIO_AF_SPI4) || \
|
||||||
|
((AF) == GPIO_AF_SPI5) || ((AF) == GPIO_AF_SPI6) || \
|
||||||
|
((AF) == GPIO_AF_UART7) || ((AF) == GPIO_AF_UART8) || \
|
||||||
|
((AF) == GPIO_AF_FMC) || ((AF) == GPIO_AF_SAI1) || \
|
||||||
|
((AF) == GPIO_AF_LTDC))
|
||||||
|
#endif /* STM32F427_437xx || STM32F429_439xx */
|
||||||
|
|
||||||
|
#if defined(STM32F412xG)
|
||||||
|
#define IS_GPIO_AF(AF) (((AF) < 16) && ((AF) != 11) && ((AF) != 14))
|
||||||
|
#endif /* STM32F412xG */
|
||||||
|
|
||||||
|
#if defined(STM32F446xx)
|
||||||
|
#define IS_GPIO_AF(AF) (((AF) < 16) && ((AF) != 11) && ((AF) != 14))
|
||||||
|
#endif /* STM32F446xx */
|
||||||
|
|
||||||
|
#if defined(STM32F469_479xx)
|
||||||
|
#define IS_GPIO_AF(AF) ((AF) < 16)
|
||||||
|
#endif /* STM32F469_479xx */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup GPIO_Legacy
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define GPIO_Mode_AIN GPIO_Mode_AN
|
||||||
|
|
||||||
|
#define GPIO_AF_OTG1_FS GPIO_AF_OTG_FS
|
||||||
|
#define GPIO_AF_OTG2_HS GPIO_AF_OTG_HS
|
||||||
|
#define GPIO_AF_OTG2_FS GPIO_AF_OTG_HS_FS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Function used to set the GPIO configuration to the default reset state ****/
|
||||||
|
void GPIO_DeInit(GPIO_TypeDef* GPIOx);
|
||||||
|
|
||||||
|
/* Initialization and Configuration functions *********************************/
|
||||||
|
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
|
||||||
|
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
|
||||||
|
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
|
||||||
|
|
||||||
|
/* GPIO Read and Write functions **********************************************/
|
||||||
|
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
|
||||||
|
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
|
||||||
|
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
|
||||||
|
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
|
||||||
|
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
|
||||||
|
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
|
||||||
|
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
|
||||||
|
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
|
||||||
|
void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
|
||||||
|
|
||||||
|
/* GPIO Alternate functions configuration function ****************************/
|
||||||
|
void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*__STM32F4xx_GPIO_H */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
@@ -0,0 +1,982 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f4xx_rcc.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @version V1.7.1
|
||||||
|
* @date 20-May-2016
|
||||||
|
* @brief This file contains all the functions prototypes for the RCC firmware library.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
|
||||||
|
*
|
||||||
|
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.st.com/software_license_agreement_liberty_v2
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __STM32F4xx_RCC_H
|
||||||
|
#define __STM32F4xx_RCC_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32F4xx_StdPeriph_Driver
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup RCC
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t SYSCLK_Frequency; /*!< SYSCLK clock frequency expressed in Hz */
|
||||||
|
uint32_t HCLK_Frequency; /*!< HCLK clock frequency expressed in Hz */
|
||||||
|
uint32_t PCLK1_Frequency; /*!< PCLK1 clock frequency expressed in Hz */
|
||||||
|
uint32_t PCLK2_Frequency; /*!< PCLK2 clock frequency expressed in Hz */
|
||||||
|
}RCC_ClocksTypeDef;
|
||||||
|
|
||||||
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_Exported_Constants
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_HSE_configuration
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_HSE_OFF ((uint8_t)0x00)
|
||||||
|
#define RCC_HSE_ON ((uint8_t)0x01)
|
||||||
|
#define RCC_HSE_Bypass ((uint8_t)0x05)
|
||||||
|
#define IS_RCC_HSE(HSE) (((HSE) == RCC_HSE_OFF) || ((HSE) == RCC_HSE_ON) || \
|
||||||
|
((HSE) == RCC_HSE_Bypass))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_LSE_Dual_Mode_Selection
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_LSE_LOWPOWER_MODE ((uint8_t)0x00)
|
||||||
|
#define RCC_LSE_HIGHDRIVE_MODE ((uint8_t)0x01)
|
||||||
|
#define IS_RCC_LSE_MODE(MODE) (((MODE) == RCC_LSE_LOWPOWER_MODE) || \
|
||||||
|
((MODE) == RCC_LSE_HIGHDRIVE_MODE))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_PLLSAIDivR_Factor
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_PLLSAIDivR_Div2 ((uint32_t)0x00000000)
|
||||||
|
#define RCC_PLLSAIDivR_Div4 ((uint32_t)0x00010000)
|
||||||
|
#define RCC_PLLSAIDivR_Div8 ((uint32_t)0x00020000)
|
||||||
|
#define RCC_PLLSAIDivR_Div16 ((uint32_t)0x00030000)
|
||||||
|
#define IS_RCC_PLLSAI_DIVR_VALUE(VALUE) (((VALUE) == RCC_PLLSAIDivR_Div2) ||\
|
||||||
|
((VALUE) == RCC_PLLSAIDivR_Div4) ||\
|
||||||
|
((VALUE) == RCC_PLLSAIDivR_Div8) ||\
|
||||||
|
((VALUE) == RCC_PLLSAIDivR_Div16))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_PLL_Clock_Source
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_PLLSource_HSI ((uint32_t)0x00000000)
|
||||||
|
#define RCC_PLLSource_HSE ((uint32_t)0x00400000)
|
||||||
|
#define IS_RCC_PLL_SOURCE(SOURCE) (((SOURCE) == RCC_PLLSource_HSI) || \
|
||||||
|
((SOURCE) == RCC_PLLSource_HSE))
|
||||||
|
#define IS_RCC_PLLM_VALUE(VALUE) ((VALUE) <= 63)
|
||||||
|
#define IS_RCC_PLLN_VALUE(VALUE) ((50 <= (VALUE)) && ((VALUE) <= 432))
|
||||||
|
#define IS_RCC_PLLP_VALUE(VALUE) (((VALUE) == 2) || ((VALUE) == 4) || ((VALUE) == 6) || ((VALUE) == 8))
|
||||||
|
#define IS_RCC_PLLQ_VALUE(VALUE) ((4 <= (VALUE)) && ((VALUE) <= 15))
|
||||||
|
#if defined(STM32F410xx) || defined(STM32F412xG) || defined(STM32F446xx) || defined(STM32F469_479xx)
|
||||||
|
#define IS_RCC_PLLR_VALUE(VALUE) ((2 <= (VALUE)) && ((VALUE) <= 7))
|
||||||
|
#endif /* STM32F410xx || STM32F412xG || STM32F446xx || STM32F469_479xx */
|
||||||
|
|
||||||
|
#define IS_RCC_PLLI2SN_VALUE(VALUE) ((50 <= (VALUE)) && ((VALUE) <= 432))
|
||||||
|
#define IS_RCC_PLLI2SR_VALUE(VALUE) ((2 <= (VALUE)) && ((VALUE) <= 7))
|
||||||
|
#define IS_RCC_PLLI2SM_VALUE(VALUE) ((VALUE) <= 63)
|
||||||
|
#define IS_RCC_PLLI2SQ_VALUE(VALUE) ((2 <= (VALUE)) && ((VALUE) <= 15))
|
||||||
|
#if defined(STM32F446xx)
|
||||||
|
#define IS_RCC_PLLI2SP_VALUE(VALUE) (((VALUE) == 2) || ((VALUE) == 4) || ((VALUE) == 6) || ((VALUE) == 8))
|
||||||
|
#define IS_RCC_PLLSAIM_VALUE(VALUE) ((VALUE) <= 63)
|
||||||
|
#elif defined(STM32F412xG)
|
||||||
|
#define IS_RCC_PLLI2SP_VALUE(VALUE) (((VALUE) == 2) || ((VALUE) == 4) || ((VALUE) == 6) || ((VALUE) == 8))
|
||||||
|
#else
|
||||||
|
#endif /* STM32F446xx */
|
||||||
|
#define IS_RCC_PLLSAIN_VALUE(VALUE) ((50 <= (VALUE)) && ((VALUE) <= 432))
|
||||||
|
#if defined(STM32F446xx) || defined(STM32F469_479xx)
|
||||||
|
#define IS_RCC_PLLSAIP_VALUE(VALUE) (((VALUE) == 2) || ((VALUE) == 4) || ((VALUE) == 6) || ((VALUE) == 8))
|
||||||
|
#endif /* STM32F446xx || STM32F469_479xx */
|
||||||
|
#define IS_RCC_PLLSAIQ_VALUE(VALUE) ((2 <= (VALUE)) && ((VALUE) <= 15))
|
||||||
|
#define IS_RCC_PLLSAIR_VALUE(VALUE) ((2 <= (VALUE)) && ((VALUE) <= 7))
|
||||||
|
|
||||||
|
#define IS_RCC_PLLSAI_DIVQ_VALUE(VALUE) ((1 <= (VALUE)) && ((VALUE) <= 32))
|
||||||
|
#define IS_RCC_PLLI2S_DIVQ_VALUE(VALUE) ((1 <= (VALUE)) && ((VALUE) <= 32))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_System_Clock_Source
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(STM32F412xG) || defined(STM32F446xx)
|
||||||
|
#define RCC_SYSCLKSource_HSI ((uint32_t)0x00000000)
|
||||||
|
#define RCC_SYSCLKSource_HSE ((uint32_t)0x00000001)
|
||||||
|
#define RCC_SYSCLKSource_PLLPCLK ((uint32_t)0x00000002)
|
||||||
|
#define RCC_SYSCLKSource_PLLRCLK ((uint32_t)0x00000003)
|
||||||
|
#define IS_RCC_SYSCLK_SOURCE(SOURCE) (((SOURCE) == RCC_SYSCLKSource_HSI) || \
|
||||||
|
((SOURCE) == RCC_SYSCLKSource_HSE) || \
|
||||||
|
((SOURCE) == RCC_SYSCLKSource_PLLPCLK) || \
|
||||||
|
((SOURCE) == RCC_SYSCLKSource_PLLRCLK))
|
||||||
|
/* Add legacy definition */
|
||||||
|
#define RCC_SYSCLKSource_PLLCLK RCC_SYSCLKSource_PLLPCLK
|
||||||
|
#endif /* STM32F446xx */
|
||||||
|
|
||||||
|
#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F401xx) || defined(STM32F410xx) || defined(STM32F411xE) || defined(STM32F469_479xx)
|
||||||
|
#define RCC_SYSCLKSource_HSI ((uint32_t)0x00000000)
|
||||||
|
#define RCC_SYSCLKSource_HSE ((uint32_t)0x00000001)
|
||||||
|
#define RCC_SYSCLKSource_PLLCLK ((uint32_t)0x00000002)
|
||||||
|
#define IS_RCC_SYSCLK_SOURCE(SOURCE) (((SOURCE) == RCC_SYSCLKSource_HSI) || \
|
||||||
|
((SOURCE) == RCC_SYSCLKSource_HSE) || \
|
||||||
|
((SOURCE) == RCC_SYSCLKSource_PLLCLK))
|
||||||
|
#endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx || STM32F410xx || STM32F411xE || STM32F469_479xx */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_AHB_Clock_Source
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_SYSCLK_Div1 ((uint32_t)0x00000000)
|
||||||
|
#define RCC_SYSCLK_Div2 ((uint32_t)0x00000080)
|
||||||
|
#define RCC_SYSCLK_Div4 ((uint32_t)0x00000090)
|
||||||
|
#define RCC_SYSCLK_Div8 ((uint32_t)0x000000A0)
|
||||||
|
#define RCC_SYSCLK_Div16 ((uint32_t)0x000000B0)
|
||||||
|
#define RCC_SYSCLK_Div64 ((uint32_t)0x000000C0)
|
||||||
|
#define RCC_SYSCLK_Div128 ((uint32_t)0x000000D0)
|
||||||
|
#define RCC_SYSCLK_Div256 ((uint32_t)0x000000E0)
|
||||||
|
#define RCC_SYSCLK_Div512 ((uint32_t)0x000000F0)
|
||||||
|
#define IS_RCC_HCLK(HCLK) (((HCLK) == RCC_SYSCLK_Div1) || ((HCLK) == RCC_SYSCLK_Div2) || \
|
||||||
|
((HCLK) == RCC_SYSCLK_Div4) || ((HCLK) == RCC_SYSCLK_Div8) || \
|
||||||
|
((HCLK) == RCC_SYSCLK_Div16) || ((HCLK) == RCC_SYSCLK_Div64) || \
|
||||||
|
((HCLK) == RCC_SYSCLK_Div128) || ((HCLK) == RCC_SYSCLK_Div256) || \
|
||||||
|
((HCLK) == RCC_SYSCLK_Div512))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_APB1_APB2_Clock_Source
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_HCLK_Div1 ((uint32_t)0x00000000)
|
||||||
|
#define RCC_HCLK_Div2 ((uint32_t)0x00001000)
|
||||||
|
#define RCC_HCLK_Div4 ((uint32_t)0x00001400)
|
||||||
|
#define RCC_HCLK_Div8 ((uint32_t)0x00001800)
|
||||||
|
#define RCC_HCLK_Div16 ((uint32_t)0x00001C00)
|
||||||
|
#define IS_RCC_PCLK(PCLK) (((PCLK) == RCC_HCLK_Div1) || ((PCLK) == RCC_HCLK_Div2) || \
|
||||||
|
((PCLK) == RCC_HCLK_Div4) || ((PCLK) == RCC_HCLK_Div8) || \
|
||||||
|
((PCLK) == RCC_HCLK_Div16))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_Interrupt_Source
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_IT_LSIRDY ((uint8_t)0x01)
|
||||||
|
#define RCC_IT_LSERDY ((uint8_t)0x02)
|
||||||
|
#define RCC_IT_HSIRDY ((uint8_t)0x04)
|
||||||
|
#define RCC_IT_HSERDY ((uint8_t)0x08)
|
||||||
|
#define RCC_IT_PLLRDY ((uint8_t)0x10)
|
||||||
|
#define RCC_IT_PLLI2SRDY ((uint8_t)0x20)
|
||||||
|
#define RCC_IT_PLLSAIRDY ((uint8_t)0x40)
|
||||||
|
#define RCC_IT_CSS ((uint8_t)0x80)
|
||||||
|
|
||||||
|
#define IS_RCC_IT(IT) ((((IT) & (uint8_t)0x80) == 0x00) && ((IT) != 0x00))
|
||||||
|
#define IS_RCC_GET_IT(IT) (((IT) == RCC_IT_LSIRDY) || ((IT) == RCC_IT_LSERDY) || \
|
||||||
|
((IT) == RCC_IT_HSIRDY) || ((IT) == RCC_IT_HSERDY) || \
|
||||||
|
((IT) == RCC_IT_PLLRDY) || ((IT) == RCC_IT_CSS) || \
|
||||||
|
((IT) == RCC_IT_PLLSAIRDY) || ((IT) == RCC_IT_PLLI2SRDY))
|
||||||
|
#define IS_RCC_CLEAR_IT(IT)((IT) != 0x00)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_LSE_Configuration
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_LSE_OFF ((uint8_t)0x00)
|
||||||
|
#define RCC_LSE_ON ((uint8_t)0x01)
|
||||||
|
#define RCC_LSE_Bypass ((uint8_t)0x04)
|
||||||
|
#define IS_RCC_LSE(LSE) (((LSE) == RCC_LSE_OFF) || ((LSE) == RCC_LSE_ON) || \
|
||||||
|
((LSE) == RCC_LSE_Bypass))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_RTC_Clock_Source
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_RTCCLKSource_LSE ((uint32_t)0x00000100)
|
||||||
|
#define RCC_RTCCLKSource_LSI ((uint32_t)0x00000200)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div2 ((uint32_t)0x00020300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div3 ((uint32_t)0x00030300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div4 ((uint32_t)0x00040300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div5 ((uint32_t)0x00050300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div6 ((uint32_t)0x00060300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div7 ((uint32_t)0x00070300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div8 ((uint32_t)0x00080300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div9 ((uint32_t)0x00090300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div10 ((uint32_t)0x000A0300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div11 ((uint32_t)0x000B0300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div12 ((uint32_t)0x000C0300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div13 ((uint32_t)0x000D0300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div14 ((uint32_t)0x000E0300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div15 ((uint32_t)0x000F0300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div16 ((uint32_t)0x00100300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div17 ((uint32_t)0x00110300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div18 ((uint32_t)0x00120300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div19 ((uint32_t)0x00130300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div20 ((uint32_t)0x00140300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div21 ((uint32_t)0x00150300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div22 ((uint32_t)0x00160300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div23 ((uint32_t)0x00170300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div24 ((uint32_t)0x00180300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div25 ((uint32_t)0x00190300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div26 ((uint32_t)0x001A0300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div27 ((uint32_t)0x001B0300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div28 ((uint32_t)0x001C0300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div29 ((uint32_t)0x001D0300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div30 ((uint32_t)0x001E0300)
|
||||||
|
#define RCC_RTCCLKSource_HSE_Div31 ((uint32_t)0x001F0300)
|
||||||
|
#define IS_RCC_RTCCLK_SOURCE(SOURCE) (((SOURCE) == RCC_RTCCLKSource_LSE) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_LSI) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div2) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div3) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div4) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div5) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div6) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div7) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div8) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div9) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div10) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div11) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div12) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div13) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div14) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div15) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div16) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div17) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div18) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div19) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div20) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div21) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div22) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div23) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div24) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div25) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div26) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div27) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div28) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div29) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div30) || \
|
||||||
|
((SOURCE) == RCC_RTCCLKSource_HSE_Div31))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(STM32F410xx)
|
||||||
|
/** @defgroup RCCEx_LPTIM1_Clock_Source RCC LPTIM1 Clock Source
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_LPTIM1CLKSOURCE_PCLK ((uint32_t)0x00000000)
|
||||||
|
#define RCC_LPTIM1CLKSOURCE_HSI ((uint32_t)RCC_DCKCFGR2_LPTIM1SEL_0)
|
||||||
|
#define RCC_LPTIM1CLKSOURCE_LSI ((uint32_t)RCC_DCKCFGR2_LPTIM1SEL_1)
|
||||||
|
#define RCC_LPTIM1CLKSOURCE_LSE ((uint32_t)RCC_DCKCFGR2_LPTIM1SEL_0 | RCC_DCKCFGR2_LPTIM1SEL_1)
|
||||||
|
|
||||||
|
#define IS_RCC_LPTIM1_CLOCKSOURCE(SOURCE) (((SOURCE) == RCC_LPTIM1CLKSOURCE_PCLK) || ((SOURCE) == RCC_LPTIM1CLKSOURCE_HSI) || \
|
||||||
|
((SOURCE) == RCC_LPTIM1CLKSOURCE_LSI) || ((SOURCE) == RCC_LPTIM1CLKSOURCE_LSE))
|
||||||
|
/* Legacy Defines */
|
||||||
|
#define IS_RCC_LPTIM1_SOURCE IS_RCC_LPTIM1_CLOCKSOURCE
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCCEx_I2S_APB_Clock_Source RCC I2S APB Clock Source
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_I2SAPBCLKSOURCE_PLLR ((uint32_t)0x00000000)
|
||||||
|
#define RCC_I2SAPBCLKSOURCE_EXT ((uint32_t)RCC_DCKCFGR_I2SSRC_0)
|
||||||
|
#define RCC_I2SAPBCLKSOURCE_PLLSRC ((uint32_t)RCC_DCKCFGR_I2SSRC_1)
|
||||||
|
#define IS_RCC_I2SCLK_SOURCE(SOURCE) (((SOURCE) == RCC_I2SAPBCLKSOURCE_PLLR) || ((SOURCE) == RCC_I2SAPBCLKSOURCE_EXT) || \
|
||||||
|
((SOURCE) == RCC_I2SAPBCLKSOURCE_PLLSRC))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* STM32F410xx */
|
||||||
|
|
||||||
|
#if defined(STM32F412xG) || defined(STM32F446xx)
|
||||||
|
/** @defgroup RCC_I2S_Clock_Source
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_I2SCLKSource_PLLI2S ((uint32_t)0x00)
|
||||||
|
#define RCC_I2SCLKSource_Ext ((uint32_t)RCC_DCKCFGR_I2S1SRC_0)
|
||||||
|
#define RCC_I2SCLKSource_PLL ((uint32_t)RCC_DCKCFGR_I2S1SRC_1)
|
||||||
|
#define RCC_I2SCLKSource_HSI_HSE ((uint32_t)RCC_DCKCFGR_I2S1SRC_0 | RCC_DCKCFGR_I2S1SRC_1)
|
||||||
|
|
||||||
|
#define IS_RCC_I2SCLK_SOURCE(SOURCE) (((SOURCE) == RCC_I2SCLKSource_PLLI2S) || ((SOURCE) == RCC_I2SCLKSource_Ext) || \
|
||||||
|
((SOURCE) == RCC_I2SCLKSource_PLL) || ((SOURCE) == RCC_I2SCLKSource_HSI_HSE))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_I2S_APBBus
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_I2SBus_APB1 ((uint8_t)0x00)
|
||||||
|
#define RCC_I2SBus_APB2 ((uint8_t)0x01)
|
||||||
|
#define IS_RCC_I2S_APBx(BUS) (((BUS) == RCC_I2SBus_APB1) || ((BUS) == RCC_I2SBus_APB2))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
#if defined(STM32F446xx)
|
||||||
|
/** @defgroup RCC_SAI_Clock_Source
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_SAICLKSource_PLLSAI ((uint32_t)0x00)
|
||||||
|
#define RCC_SAICLKSource_PLLI2S ((uint32_t)RCC_DCKCFGR_SAI1SRC_0)
|
||||||
|
#define RCC_SAICLKSource_PLL ((uint32_t)RCC_DCKCFGR_SAI1SRC_1)
|
||||||
|
#define RCC_SAICLKSource_HSI_HSE ((uint32_t)RCC_DCKCFGR_SAI1SRC_0 | RCC_DCKCFGR_SAI1SRC_1)
|
||||||
|
|
||||||
|
#define IS_RCC_SAICLK_SOURCE(SOURCE) (((SOURCE) == RCC_SAICLKSource_PLLSAI) || ((SOURCE) == RCC_SAICLKSource_PLLI2S) || \
|
||||||
|
((SOURCE) == RCC_SAICLKSource_PLL) || ((SOURCE) == RCC_SAICLKSource_HSI_HSE))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_SAI_Instance
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_SAIInstance_SAI1 ((uint8_t)0x00)
|
||||||
|
#define RCC_SAIInstance_SAI2 ((uint8_t)0x01)
|
||||||
|
#define IS_RCC_SAI_INSTANCE(BUS) (((BUS) == RCC_SAIInstance_SAI1) || ((BUS) == RCC_SAIInstance_SAI2))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
#endif /* STM32F446xx */
|
||||||
|
#endif /* STM32F412xG || STM32F446xx */
|
||||||
|
|
||||||
|
#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F401xx) || defined(STM32F411xE) || defined(STM32F469_479xx)
|
||||||
|
/** @defgroup RCC_I2S_Clock_Source
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_I2S2CLKSource_PLLI2S ((uint8_t)0x00)
|
||||||
|
#define RCC_I2S2CLKSource_Ext ((uint8_t)0x01)
|
||||||
|
|
||||||
|
#define IS_RCC_I2SCLK_SOURCE(SOURCE) (((SOURCE) == RCC_I2S2CLKSource_PLLI2S) || ((SOURCE) == RCC_I2S2CLKSource_Ext))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_SAI_BlockA_Clock_Source
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_SAIACLKSource_PLLSAI ((uint32_t)0x00000000)
|
||||||
|
#define RCC_SAIACLKSource_PLLI2S ((uint32_t)0x00100000)
|
||||||
|
#define RCC_SAIACLKSource_Ext ((uint32_t)0x00200000)
|
||||||
|
|
||||||
|
#define IS_RCC_SAIACLK_SOURCE(SOURCE) (((SOURCE) == RCC_SAIACLKSource_PLLI2S) ||\
|
||||||
|
((SOURCE) == RCC_SAIACLKSource_PLLSAI) ||\
|
||||||
|
((SOURCE) == RCC_SAIACLKSource_Ext))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_SAI_BlockB_Clock_Source
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_SAIBCLKSource_PLLSAI ((uint32_t)0x00000000)
|
||||||
|
#define RCC_SAIBCLKSource_PLLI2S ((uint32_t)0x00400000)
|
||||||
|
#define RCC_SAIBCLKSource_Ext ((uint32_t)0x00800000)
|
||||||
|
|
||||||
|
#define IS_RCC_SAIBCLK_SOURCE(SOURCE) (((SOURCE) == RCC_SAIBCLKSource_PLLI2S) ||\
|
||||||
|
((SOURCE) == RCC_SAIBCLKSource_PLLSAI) ||\
|
||||||
|
((SOURCE) == RCC_SAIBCLKSource_Ext))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
#endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx || STM32F411xE || STM32F469_479xx */
|
||||||
|
|
||||||
|
/** @defgroup RCC_TIM_PRescaler_Selection
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_TIMPrescDesactivated ((uint8_t)0x00)
|
||||||
|
#define RCC_TIMPrescActivated ((uint8_t)0x01)
|
||||||
|
|
||||||
|
#define IS_RCC_TIMCLK_PRESCALER(VALUE) (((VALUE) == RCC_TIMPrescDesactivated) || ((VALUE) == RCC_TIMPrescActivated))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(STM32F469_479xx)
|
||||||
|
/** @defgroup RCC_DSI_Clock_Source_Selection
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_DSICLKSource_PHY ((uint8_t)0x00)
|
||||||
|
#define RCC_DSICLKSource_PLLR ((uint8_t)0x01)
|
||||||
|
#define IS_RCC_DSI_CLOCKSOURCE(CLKSOURCE) (((CLKSOURCE) == RCC_DSICLKSource_PHY) || \
|
||||||
|
((CLKSOURCE) == RCC_DSICLKSource_PLLR))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
#endif /* STM32F469_479xx */
|
||||||
|
|
||||||
|
#if defined(STM32F412xG) || defined(STM32F446xx) || defined(STM32F469_479xx)
|
||||||
|
/** @defgroup RCC_SDIO_Clock_Source_Selection
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_SDIOCLKSource_48MHZ ((uint8_t)0x00)
|
||||||
|
#define RCC_SDIOCLKSource_SYSCLK ((uint8_t)0x01)
|
||||||
|
#define IS_RCC_SDIO_CLOCKSOURCE(CLKSOURCE) (((CLKSOURCE) == RCC_SDIOCLKSource_48MHZ) || \
|
||||||
|
((CLKSOURCE) == RCC_SDIOCLKSource_SYSCLK))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup RCC_48MHZ_Clock_Source_Selection
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#if defined(STM32F446xx) || defined(STM32F469_479xx)
|
||||||
|
#define RCC_48MHZCLKSource_PLL ((uint8_t)0x00)
|
||||||
|
#define RCC_48MHZCLKSource_PLLSAI ((uint8_t)0x01)
|
||||||
|
#define IS_RCC_48MHZ_CLOCKSOURCE(CLKSOURCE) (((CLKSOURCE) == RCC_48MHZCLKSource_PLL) || \
|
||||||
|
((CLKSOURCE) == RCC_48MHZCLKSource_PLLSAI))
|
||||||
|
#endif /* STM32F446xx || STM32F469_479xx */
|
||||||
|
#if defined(STM32F412xG)
|
||||||
|
#define RCC_CK48CLKSOURCE_PLLQ ((uint8_t)0x00)
|
||||||
|
#define RCC_CK48CLKSOURCE_PLLI2SQ ((uint8_t)0x01) /* Only for STM32F412xG Devices */
|
||||||
|
#define IS_RCC_48MHZ_CLOCKSOURCE(CLKSOURCE) (((CLKSOURCE) == RCC_CK48CLKSOURCE_PLLQ) || \
|
||||||
|
((CLKSOURCE) == RCC_CK48CLKSOURCE_PLLI2SQ))
|
||||||
|
#endif /* STM32F412xG */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
#endif /* STM32F412xG || STM32F446xx || STM32F469_479xx */
|
||||||
|
|
||||||
|
#if defined(STM32F446xx)
|
||||||
|
/** @defgroup RCC_SPDIFRX_Clock_Source_Selection
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_SPDIFRXCLKSource_PLLR ((uint8_t)0x00)
|
||||||
|
#define RCC_SPDIFRXCLKSource_PLLI2SP ((uint8_t)0x01)
|
||||||
|
#define IS_RCC_SPDIFRX_CLOCKSOURCE(CLKSOURCE) (((CLKSOURCE) == RCC_SPDIFRXCLKSource_PLLR) || \
|
||||||
|
((CLKSOURCE) == RCC_SPDIFRXCLKSource_PLLI2SP))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_CEC_Clock_Source_Selection
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_CECCLKSource_HSIDiv488 ((uint8_t)0x00)
|
||||||
|
#define RCC_CECCLKSource_LSE ((uint8_t)0x01)
|
||||||
|
#define IS_RCC_CEC_CLOCKSOURCE(CLKSOURCE) (((CLKSOURCE) == RCC_CECCLKSource_HSIDiv488) || \
|
||||||
|
((CLKSOURCE) == RCC_CECCLKSource_LSE))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_AHB1_ClockGating
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_AHB1ClockGating_APB1Bridge ((uint32_t)0x00000001)
|
||||||
|
#define RCC_AHB1ClockGating_APB2Bridge ((uint32_t)0x00000002)
|
||||||
|
#define RCC_AHB1ClockGating_CM4DBG ((uint32_t)0x00000004)
|
||||||
|
#define RCC_AHB1ClockGating_SPARE ((uint32_t)0x00000008)
|
||||||
|
#define RCC_AHB1ClockGating_SRAM ((uint32_t)0x00000010)
|
||||||
|
#define RCC_AHB1ClockGating_FLITF ((uint32_t)0x00000020)
|
||||||
|
#define RCC_AHB1ClockGating_RCC ((uint32_t)0x00000040)
|
||||||
|
|
||||||
|
#define IS_RCC_AHB1_CLOCKGATING(PERIPH) ((((PERIPH) & 0xFFFFFF80) == 0x00) && ((PERIPH) != 0x00))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
#endif /* STM32F446xx */
|
||||||
|
|
||||||
|
#if defined(STM32F410xx) || defined(STM32F412xG) || defined(STM32F446xx)
|
||||||
|
/** @defgroup RCC_FMPI2C1_Clock_Source
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_FMPI2C1CLKSource_APB1 ((uint32_t)0x00)
|
||||||
|
#define RCC_FMPI2C1CLKSource_SYSCLK ((uint32_t)RCC_DCKCFGR2_FMPI2C1SEL_0)
|
||||||
|
#define RCC_FMPI2C1CLKSource_HSI ((uint32_t)RCC_DCKCFGR2_FMPI2C1SEL_1)
|
||||||
|
|
||||||
|
#define IS_RCC_FMPI2C1_CLOCKSOURCE(SOURCE) (((SOURCE) == RCC_FMPI2C1CLKSource_APB1) || ((SOURCE) == RCC_FMPI2C1CLKSource_SYSCLK) || \
|
||||||
|
((SOURCE) == RCC_FMPI2C1CLKSource_HSI))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
#endif /* STM32F410xx || STM32F412xG || STM32F446xx */
|
||||||
|
|
||||||
|
#if defined(STM32F412xG)
|
||||||
|
/** @defgroup RCC_DFSDM_Clock_Source
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_DFSDM1CLKSource_APB ((uint8_t)0x00)
|
||||||
|
#define RCC_DFSDM1CLKSource_SYS ((uint8_t)0x01)
|
||||||
|
#define IS_RCC_DFSDM1CLK_SOURCE(SOURCE) (((SOURCE) == RCC_DFSDM1CLKSource_APB) || ((SOURCE) == RCC_DFSDM1CLKSource_SYS))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_DFSDM_Audio_Clock_Source RCC DFSDM Audio Clock Source
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_DFSDM1AUDIOCLKSOURCE_I2SAPB1 ((uint32_t)0x00000000)
|
||||||
|
#define RCC_DFSDM1AUDIOCLKSOURCE_I2SAPB2 ((uint32_t)RCC_DCKCFGR_CKDFSDM1ASEL)
|
||||||
|
#define IS_RCC_DFSDMACLK_SOURCE(SOURCE) (((SOURCE) == RCC_DFSDM1AUDIOCLKSOURCE_I2SAPB1) || ((SOURCE) == RCC_DFSDM1AUDIOCLKSOURCE_I2SAPB2))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
#endif /* STM32F412xG */
|
||||||
|
|
||||||
|
/** @defgroup RCC_AHB1_Peripherals
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_AHB1Periph_GPIOA ((uint32_t)0x00000001)
|
||||||
|
#define RCC_AHB1Periph_GPIOB ((uint32_t)0x00000002)
|
||||||
|
#define RCC_AHB1Periph_GPIOC ((uint32_t)0x00000004)
|
||||||
|
#define RCC_AHB1Periph_GPIOD ((uint32_t)0x00000008)
|
||||||
|
#define RCC_AHB1Periph_GPIOE ((uint32_t)0x00000010)
|
||||||
|
#define RCC_AHB1Periph_GPIOF ((uint32_t)0x00000020)
|
||||||
|
#define RCC_AHB1Periph_GPIOG ((uint32_t)0x00000040)
|
||||||
|
#define RCC_AHB1Periph_GPIOH ((uint32_t)0x00000080)
|
||||||
|
#define RCC_AHB1Periph_GPIOI ((uint32_t)0x00000100)
|
||||||
|
#define RCC_AHB1Periph_GPIOJ ((uint32_t)0x00000200)
|
||||||
|
#define RCC_AHB1Periph_GPIOK ((uint32_t)0x00000400)
|
||||||
|
#define RCC_AHB1Periph_CRC ((uint32_t)0x00001000)
|
||||||
|
#define RCC_AHB1Periph_FLITF ((uint32_t)0x00008000)
|
||||||
|
#define RCC_AHB1Periph_SRAM1 ((uint32_t)0x00010000)
|
||||||
|
#define RCC_AHB1Periph_SRAM2 ((uint32_t)0x00020000)
|
||||||
|
#define RCC_AHB1Periph_BKPSRAM ((uint32_t)0x00040000)
|
||||||
|
#define RCC_AHB1Periph_SRAM3 ((uint32_t)0x00080000)
|
||||||
|
#define RCC_AHB1Periph_CCMDATARAMEN ((uint32_t)0x00100000)
|
||||||
|
#define RCC_AHB1Periph_DMA1 ((uint32_t)0x00200000)
|
||||||
|
#define RCC_AHB1Periph_DMA2 ((uint32_t)0x00400000)
|
||||||
|
#define RCC_AHB1Periph_DMA2D ((uint32_t)0x00800000)
|
||||||
|
#define RCC_AHB1Periph_ETH_MAC ((uint32_t)0x02000000)
|
||||||
|
#define RCC_AHB1Periph_ETH_MAC_Tx ((uint32_t)0x04000000)
|
||||||
|
#define RCC_AHB1Periph_ETH_MAC_Rx ((uint32_t)0x08000000)
|
||||||
|
#define RCC_AHB1Periph_ETH_MAC_PTP ((uint32_t)0x10000000)
|
||||||
|
#define RCC_AHB1Periph_OTG_HS ((uint32_t)0x20000000)
|
||||||
|
#define RCC_AHB1Periph_OTG_HS_ULPI ((uint32_t)0x40000000)
|
||||||
|
#if defined(STM32F410xx)
|
||||||
|
#define RCC_AHB1Periph_RNG ((uint32_t)0x80000000)
|
||||||
|
#endif /* STM32F410xx */
|
||||||
|
#define IS_RCC_AHB1_CLOCK_PERIPH(PERIPH) ((((PERIPH) & 0x010BE800) == 0x00) && ((PERIPH) != 0x00))
|
||||||
|
#define IS_RCC_AHB1_RESET_PERIPH(PERIPH) ((((PERIPH) & 0x51FE800) == 0x00) && ((PERIPH) != 0x00))
|
||||||
|
#define IS_RCC_AHB1_LPMODE_PERIPH(PERIPH) ((((PERIPH) & 0x01106800) == 0x00) && ((PERIPH) != 0x00))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_AHB2_Peripherals
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_AHB2Periph_DCMI ((uint32_t)0x00000001)
|
||||||
|
#define RCC_AHB2Periph_CRYP ((uint32_t)0x00000010)
|
||||||
|
#define RCC_AHB2Periph_HASH ((uint32_t)0x00000020)
|
||||||
|
#if defined(STM32F40_41xxx) || defined(STM32F412xG) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F469_479xx)
|
||||||
|
#define RCC_AHB2Periph_RNG ((uint32_t)0x00000040)
|
||||||
|
#endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F469_479xx */
|
||||||
|
#define RCC_AHB2Periph_OTG_FS ((uint32_t)0x00000080)
|
||||||
|
#define IS_RCC_AHB2_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFF0E) == 0x00) && ((PERIPH) != 0x00))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_AHB3_Peripherals
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#if defined(STM32F40_41xxx)
|
||||||
|
#define RCC_AHB3Periph_FSMC ((uint32_t)0x00000001)
|
||||||
|
#define IS_RCC_AHB3_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFFFE) == 0x00) && ((PERIPH) != 0x00))
|
||||||
|
#endif /* STM32F40_41xxx */
|
||||||
|
|
||||||
|
#if defined(STM32F427_437xx) || defined(STM32F429_439xx)
|
||||||
|
#define RCC_AHB3Periph_FMC ((uint32_t)0x00000001)
|
||||||
|
#define IS_RCC_AHB3_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFFFE) == 0x00) && ((PERIPH) != 0x00))
|
||||||
|
#endif /* STM32F427_437xx || STM32F429_439xx */
|
||||||
|
|
||||||
|
#if defined(STM32F446xx) || defined(STM32F469_479xx)
|
||||||
|
#define RCC_AHB3Periph_FMC ((uint32_t)0x00000001)
|
||||||
|
#define RCC_AHB3Periph_QSPI ((uint32_t)0x00000002)
|
||||||
|
#define IS_RCC_AHB3_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFFFC) == 0x00) && ((PERIPH) != 0x00))
|
||||||
|
#endif /* STM32F446xx || STM32F469_479xx */
|
||||||
|
|
||||||
|
#if defined(STM32F412xG)
|
||||||
|
#define RCC_AHB3Periph_FSMC ((uint32_t)0x00000001)
|
||||||
|
#define RCC_AHB3Periph_QSPI ((uint32_t)0x00000002)
|
||||||
|
#define IS_RCC_AHB3_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFFFC) == 0x00) && ((PERIPH) != 0x00))
|
||||||
|
#endif /* STM32F412xG */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_APB1_Peripherals
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_APB1Periph_TIM2 ((uint32_t)0x00000001)
|
||||||
|
#define RCC_APB1Periph_TIM3 ((uint32_t)0x00000002)
|
||||||
|
#define RCC_APB1Periph_TIM4 ((uint32_t)0x00000004)
|
||||||
|
#define RCC_APB1Periph_TIM5 ((uint32_t)0x00000008)
|
||||||
|
#define RCC_APB1Periph_TIM6 ((uint32_t)0x00000010)
|
||||||
|
#define RCC_APB1Periph_TIM7 ((uint32_t)0x00000020)
|
||||||
|
#define RCC_APB1Periph_TIM12 ((uint32_t)0x00000040)
|
||||||
|
#define RCC_APB1Periph_TIM13 ((uint32_t)0x00000080)
|
||||||
|
#define RCC_APB1Periph_TIM14 ((uint32_t)0x00000100)
|
||||||
|
#if defined(STM32F410xx)
|
||||||
|
#define RCC_APB1Periph_LPTIM1 ((uint32_t)0x00000200)
|
||||||
|
#endif /* STM32F410xx */
|
||||||
|
#define RCC_APB1Periph_WWDG ((uint32_t)0x00000800)
|
||||||
|
#define RCC_APB1Periph_SPI2 ((uint32_t)0x00004000)
|
||||||
|
#define RCC_APB1Periph_SPI3 ((uint32_t)0x00008000)
|
||||||
|
#if defined(STM32F446xx)
|
||||||
|
#define RCC_APB1Periph_SPDIFRX ((uint32_t)0x00010000)
|
||||||
|
#endif /* STM32F446xx */
|
||||||
|
#define RCC_APB1Periph_USART2 ((uint32_t)0x00020000)
|
||||||
|
#define RCC_APB1Periph_USART3 ((uint32_t)0x00040000)
|
||||||
|
#define RCC_APB1Periph_UART4 ((uint32_t)0x00080000)
|
||||||
|
#define RCC_APB1Periph_UART5 ((uint32_t)0x00100000)
|
||||||
|
#define RCC_APB1Periph_I2C1 ((uint32_t)0x00200000)
|
||||||
|
#define RCC_APB1Periph_I2C2 ((uint32_t)0x00400000)
|
||||||
|
#define RCC_APB1Periph_I2C3 ((uint32_t)0x00800000)
|
||||||
|
#if defined(STM32F410xx) || defined(STM32F412xG) || defined(STM32F446xx)
|
||||||
|
#define RCC_APB1Periph_FMPI2C1 ((uint32_t)0x01000000)
|
||||||
|
#endif /* STM32F410xx || STM32F446xx */
|
||||||
|
#define RCC_APB1Periph_CAN1 ((uint32_t)0x02000000)
|
||||||
|
#define RCC_APB1Periph_CAN2 ((uint32_t)0x04000000)
|
||||||
|
#if defined(STM32F446xx)
|
||||||
|
#define RCC_APB1Periph_CEC ((uint32_t)0x08000000)
|
||||||
|
#endif /* STM32F446xx */
|
||||||
|
#define RCC_APB1Periph_PWR ((uint32_t)0x10000000)
|
||||||
|
#define RCC_APB1Periph_DAC ((uint32_t)0x20000000)
|
||||||
|
#define RCC_APB1Periph_UART7 ((uint32_t)0x40000000)
|
||||||
|
#define RCC_APB1Periph_UART8 ((uint32_t)0x80000000)
|
||||||
|
#define IS_RCC_APB1_PERIPH(PERIPH) ((((PERIPH) & 0x00003600) == 0x00) && ((PERIPH) != 0x00))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_APB2_Peripherals
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_APB2Periph_TIM1 ((uint32_t)0x00000001)
|
||||||
|
#define RCC_APB2Periph_TIM8 ((uint32_t)0x00000002)
|
||||||
|
#define RCC_APB2Periph_USART1 ((uint32_t)0x00000010)
|
||||||
|
#define RCC_APB2Periph_USART6 ((uint32_t)0x00000020)
|
||||||
|
#define RCC_APB2Periph_ADC ((uint32_t)0x00000100)
|
||||||
|
#define RCC_APB2Periph_ADC1 ((uint32_t)0x00000100)
|
||||||
|
#define RCC_APB2Periph_ADC2 ((uint32_t)0x00000200)
|
||||||
|
#define RCC_APB2Periph_ADC3 ((uint32_t)0x00000400)
|
||||||
|
#define RCC_APB2Periph_SDIO ((uint32_t)0x00000800)
|
||||||
|
#define RCC_APB2Periph_SPI1 ((uint32_t)0x00001000)
|
||||||
|
#define RCC_APB2Periph_SPI4 ((uint32_t)0x00002000)
|
||||||
|
#define RCC_APB2Periph_SYSCFG ((uint32_t)0x00004000)
|
||||||
|
#define RCC_APB2Periph_TIM9 ((uint32_t)0x00010000)
|
||||||
|
#define RCC_APB2Periph_TIM10 ((uint32_t)0x00020000)
|
||||||
|
#define RCC_APB2Periph_TIM11 ((uint32_t)0x00040000)
|
||||||
|
#define RCC_APB2Periph_SPI5 ((uint32_t)0x00100000)
|
||||||
|
#define RCC_APB2Periph_SPI6 ((uint32_t)0x00200000)
|
||||||
|
#define RCC_APB2Periph_SAI1 ((uint32_t)0x00400000)
|
||||||
|
#if defined(STM32F446xx) || defined(STM32F469_479xx)
|
||||||
|
#define RCC_APB2Periph_SAI2 ((uint32_t)0x00800000)
|
||||||
|
#endif /* STM32F446xx || STM32F469_479xx */
|
||||||
|
#define RCC_APB2Periph_LTDC ((uint32_t)0x04000000)
|
||||||
|
#if defined(STM32F469_479xx)
|
||||||
|
#define RCC_APB2Periph_DSI ((uint32_t)0x08000000)
|
||||||
|
#endif /* STM32F469_479xx */
|
||||||
|
#if defined(STM32F412xG)
|
||||||
|
#define RCC_APB2Periph_DFSDM ((uint32_t)0x01000000)
|
||||||
|
#endif /* STM32F412xG */
|
||||||
|
|
||||||
|
#define IS_RCC_APB2_PERIPH(PERIPH) ((((PERIPH) & 0xF20880CC) == 0x00) && ((PERIPH) != 0x00))
|
||||||
|
#define IS_RCC_APB2_RESET_PERIPH(PERIPH) ((((PERIPH) & 0xF20886CC) == 0x00) && ((PERIPH) != 0x00))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_MCO1_Clock_Source_Prescaler
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_MCO1Source_HSI ((uint32_t)0x00000000)
|
||||||
|
#define RCC_MCO1Source_LSE ((uint32_t)0x00200000)
|
||||||
|
#define RCC_MCO1Source_HSE ((uint32_t)0x00400000)
|
||||||
|
#define RCC_MCO1Source_PLLCLK ((uint32_t)0x00600000)
|
||||||
|
#define RCC_MCO1Div_1 ((uint32_t)0x00000000)
|
||||||
|
#define RCC_MCO1Div_2 ((uint32_t)0x04000000)
|
||||||
|
#define RCC_MCO1Div_3 ((uint32_t)0x05000000)
|
||||||
|
#define RCC_MCO1Div_4 ((uint32_t)0x06000000)
|
||||||
|
#define RCC_MCO1Div_5 ((uint32_t)0x07000000)
|
||||||
|
#define IS_RCC_MCO1SOURCE(SOURCE) (((SOURCE) == RCC_MCO1Source_HSI) || ((SOURCE) == RCC_MCO1Source_LSE) || \
|
||||||
|
((SOURCE) == RCC_MCO1Source_HSE) || ((SOURCE) == RCC_MCO1Source_PLLCLK))
|
||||||
|
|
||||||
|
#define IS_RCC_MCO1DIV(DIV) (((DIV) == RCC_MCO1Div_1) || ((DIV) == RCC_MCO1Div_2) || \
|
||||||
|
((DIV) == RCC_MCO1Div_3) || ((DIV) == RCC_MCO1Div_4) || \
|
||||||
|
((DIV) == RCC_MCO1Div_5))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_MCO2_Clock_Source_Prescaler
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_MCO2Source_SYSCLK ((uint32_t)0x00000000)
|
||||||
|
#define RCC_MCO2Source_PLLI2SCLK ((uint32_t)0x40000000)
|
||||||
|
#define RCC_MCO2Source_HSE ((uint32_t)0x80000000)
|
||||||
|
#define RCC_MCO2Source_PLLCLK ((uint32_t)0xC0000000)
|
||||||
|
#define RCC_MCO2Div_1 ((uint32_t)0x00000000)
|
||||||
|
#define RCC_MCO2Div_2 ((uint32_t)0x20000000)
|
||||||
|
#define RCC_MCO2Div_3 ((uint32_t)0x28000000)
|
||||||
|
#define RCC_MCO2Div_4 ((uint32_t)0x30000000)
|
||||||
|
#define RCC_MCO2Div_5 ((uint32_t)0x38000000)
|
||||||
|
#define IS_RCC_MCO2SOURCE(SOURCE) (((SOURCE) == RCC_MCO2Source_SYSCLK) || ((SOURCE) == RCC_MCO2Source_PLLI2SCLK)|| \
|
||||||
|
((SOURCE) == RCC_MCO2Source_HSE) || ((SOURCE) == RCC_MCO2Source_PLLCLK))
|
||||||
|
|
||||||
|
#define IS_RCC_MCO2DIV(DIV) (((DIV) == RCC_MCO2Div_1) || ((DIV) == RCC_MCO2Div_2) || \
|
||||||
|
((DIV) == RCC_MCO2Div_3) || ((DIV) == RCC_MCO2Div_4) || \
|
||||||
|
((DIV) == RCC_MCO2Div_5))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup RCC_Flag
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RCC_FLAG_HSIRDY ((uint8_t)0x21)
|
||||||
|
#define RCC_FLAG_HSERDY ((uint8_t)0x31)
|
||||||
|
#define RCC_FLAG_PLLRDY ((uint8_t)0x39)
|
||||||
|
#define RCC_FLAG_PLLI2SRDY ((uint8_t)0x3B)
|
||||||
|
#define RCC_FLAG_PLLSAIRDY ((uint8_t)0x3D)
|
||||||
|
#define RCC_FLAG_LSERDY ((uint8_t)0x41)
|
||||||
|
#define RCC_FLAG_LSIRDY ((uint8_t)0x61)
|
||||||
|
#define RCC_FLAG_BORRST ((uint8_t)0x79)
|
||||||
|
#define RCC_FLAG_PINRST ((uint8_t)0x7A)
|
||||||
|
#define RCC_FLAG_PORRST ((uint8_t)0x7B)
|
||||||
|
#define RCC_FLAG_SFTRST ((uint8_t)0x7C)
|
||||||
|
#define RCC_FLAG_IWDGRST ((uint8_t)0x7D)
|
||||||
|
#define RCC_FLAG_WWDGRST ((uint8_t)0x7E)
|
||||||
|
#define RCC_FLAG_LPWRRST ((uint8_t)0x7F)
|
||||||
|
|
||||||
|
#define IS_RCC_FLAG(FLAG) (((FLAG) == RCC_FLAG_HSIRDY) || ((FLAG) == RCC_FLAG_HSERDY) || \
|
||||||
|
((FLAG) == RCC_FLAG_PLLRDY) || ((FLAG) == RCC_FLAG_LSERDY) || \
|
||||||
|
((FLAG) == RCC_FLAG_LSIRDY) || ((FLAG) == RCC_FLAG_BORRST) || \
|
||||||
|
((FLAG) == RCC_FLAG_PINRST) || ((FLAG) == RCC_FLAG_PORRST) || \
|
||||||
|
((FLAG) == RCC_FLAG_SFTRST) || ((FLAG) == RCC_FLAG_IWDGRST)|| \
|
||||||
|
((FLAG) == RCC_FLAG_WWDGRST) || ((FLAG) == RCC_FLAG_LPWRRST)|| \
|
||||||
|
((FLAG) == RCC_FLAG_PLLI2SRDY)|| ((FLAG) == RCC_FLAG_PLLSAIRDY))
|
||||||
|
|
||||||
|
#define IS_RCC_CALIBRATION_VALUE(VALUE) ((VALUE) <= 0x1F)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Function used to set the RCC clock configuration to the default reset state */
|
||||||
|
void RCC_DeInit(void);
|
||||||
|
|
||||||
|
/* Internal/external clocks, PLL, CSS and MCO configuration functions *********/
|
||||||
|
void RCC_HSEConfig(uint8_t RCC_HSE);
|
||||||
|
ErrorStatus RCC_WaitForHSEStartUp(void);
|
||||||
|
void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue);
|
||||||
|
void RCC_HSICmd(FunctionalState NewState);
|
||||||
|
void RCC_LSEConfig(uint8_t RCC_LSE);
|
||||||
|
void RCC_LSICmd(FunctionalState NewState);
|
||||||
|
|
||||||
|
void RCC_PLLCmd(FunctionalState NewState);
|
||||||
|
|
||||||
|
#if defined(STM32F410xx) || defined(STM32F412xG) || defined(STM32F446xx) || defined(STM32F469_479xx)
|
||||||
|
void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ, uint32_t PLLR);
|
||||||
|
#endif /* STM32F410xx || STM32F412xG || STM32F446xx || STM32F469_479xx */
|
||||||
|
|
||||||
|
#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F401xx) || defined(STM32F411xE)
|
||||||
|
void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ);
|
||||||
|
#endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx || STM32F411xE */
|
||||||
|
|
||||||
|
void RCC_PLLI2SCmd(FunctionalState NewState);
|
||||||
|
|
||||||
|
#if defined(STM32F40_41xxx) || defined(STM32F401xx)
|
||||||
|
void RCC_PLLI2SConfig(uint32_t PLLI2SN, uint32_t PLLI2SR);
|
||||||
|
#endif /* STM32F40_41xxx || STM32F401xx */
|
||||||
|
#if defined(STM32F411xE)
|
||||||
|
void RCC_PLLI2SConfig(uint32_t PLLI2SN, uint32_t PLLI2SR, uint32_t PLLI2SM);
|
||||||
|
#endif /* STM32F411xE */
|
||||||
|
#if defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F469_479xx)
|
||||||
|
void RCC_PLLI2SConfig(uint32_t PLLI2SN, uint32_t PLLI2SQ, uint32_t PLLI2SR);
|
||||||
|
#endif /* STM32F427_437xx || STM32F429_439xx || STM32F469_479xx */
|
||||||
|
#if defined(STM32F412xG) || defined(STM32F446xx)
|
||||||
|
void RCC_PLLI2SConfig(uint32_t PLLI2SM, uint32_t PLLI2SN, uint32_t PLLI2SP, uint32_t PLLI2SQ, uint32_t PLLI2SR);
|
||||||
|
#endif /* STM32F412xG || STM32F446xx */
|
||||||
|
|
||||||
|
void RCC_PLLSAICmd(FunctionalState NewState);
|
||||||
|
#if defined(STM32F469_479xx)
|
||||||
|
void RCC_PLLSAIConfig(uint32_t PLLSAIN, uint32_t PLLSAIP, uint32_t PLLSAIQ, uint32_t PLLSAIR);
|
||||||
|
#endif /* STM32F469_479xx */
|
||||||
|
#if defined(STM32F446xx)
|
||||||
|
void RCC_PLLSAIConfig(uint32_t PLLSAIM, uint32_t PLLSAIN, uint32_t PLLSAIP, uint32_t PLLSAIQ);
|
||||||
|
#endif /* STM32F446xx */
|
||||||
|
#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F401xx) || defined(STM32F411xE)
|
||||||
|
void RCC_PLLSAIConfig(uint32_t PLLSAIN, uint32_t PLLSAIQ, uint32_t PLLSAIR);
|
||||||
|
#endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx || STM32F411xE */
|
||||||
|
|
||||||
|
void RCC_ClockSecuritySystemCmd(FunctionalState NewState);
|
||||||
|
void RCC_MCO1Config(uint32_t RCC_MCO1Source, uint32_t RCC_MCO1Div);
|
||||||
|
void RCC_MCO2Config(uint32_t RCC_MCO2Source, uint32_t RCC_MCO2Div);
|
||||||
|
|
||||||
|
/* System, AHB and APB busses clocks configuration functions ******************/
|
||||||
|
void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);
|
||||||
|
uint8_t RCC_GetSYSCLKSource(void);
|
||||||
|
void RCC_HCLKConfig(uint32_t RCC_SYSCLK);
|
||||||
|
void RCC_PCLK1Config(uint32_t RCC_HCLK);
|
||||||
|
void RCC_PCLK2Config(uint32_t RCC_HCLK);
|
||||||
|
void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks);
|
||||||
|
|
||||||
|
/* Peripheral clocks configuration functions **********************************/
|
||||||
|
void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource);
|
||||||
|
void RCC_RTCCLKCmd(FunctionalState NewState);
|
||||||
|
void RCC_BackupResetCmd(FunctionalState NewState);
|
||||||
|
|
||||||
|
#if defined(STM32F412xG) || defined(STM32F446xx)
|
||||||
|
void RCC_I2SCLKConfig(uint32_t RCC_I2SAPBx, uint32_t RCC_I2SCLKSource);
|
||||||
|
#if defined(STM32F446xx)
|
||||||
|
void RCC_SAICLKConfig(uint32_t RCC_SAIInstance, uint32_t RCC_SAICLKSource);
|
||||||
|
#endif /* STM32F446xx */
|
||||||
|
#endif /* STM32F412xG || STM32F446xx */
|
||||||
|
|
||||||
|
#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F401xx) || defined(STM32F410xx) || defined(STM32F411xE) || defined(STM32F469_479xx)
|
||||||
|
void RCC_I2SCLKConfig(uint32_t RCC_I2SCLKSource);
|
||||||
|
#endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx || STM32F410xx || STM32F411xE || STM32F469_479xx */
|
||||||
|
|
||||||
|
#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F469_479xx)
|
||||||
|
void RCC_SAIBlockACLKConfig(uint32_t RCC_SAIBlockACLKSource);
|
||||||
|
void RCC_SAIBlockBCLKConfig(uint32_t RCC_SAIBlockBCLKSource);
|
||||||
|
#endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F469_479xx */
|
||||||
|
|
||||||
|
void RCC_SAIPLLI2SClkDivConfig(uint32_t RCC_PLLI2SDivQ);
|
||||||
|
void RCC_SAIPLLSAIClkDivConfig(uint32_t RCC_PLLSAIDivQ);
|
||||||
|
|
||||||
|
void RCC_LTDCCLKDivConfig(uint32_t RCC_PLLSAIDivR);
|
||||||
|
void RCC_TIMCLKPresConfig(uint32_t RCC_TIMCLKPrescaler);
|
||||||
|
|
||||||
|
void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
|
||||||
|
void RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
|
||||||
|
void RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState);
|
||||||
|
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
|
||||||
|
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
|
||||||
|
|
||||||
|
void RCC_AHB1PeriphResetCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
|
||||||
|
void RCC_AHB2PeriphResetCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
|
||||||
|
void RCC_AHB3PeriphResetCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState);
|
||||||
|
void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
|
||||||
|
void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
|
||||||
|
|
||||||
|
void RCC_AHB1PeriphClockLPModeCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
|
||||||
|
void RCC_AHB2PeriphClockLPModeCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
|
||||||
|
void RCC_AHB3PeriphClockLPModeCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState);
|
||||||
|
void RCC_APB1PeriphClockLPModeCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
|
||||||
|
void RCC_APB2PeriphClockLPModeCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
|
||||||
|
|
||||||
|
/* Features available only for STM32F410xx/STM32F411xx/STM32F446xx/STM32F469_479xx devices */
|
||||||
|
void RCC_LSEModeConfig(uint8_t RCC_Mode);
|
||||||
|
|
||||||
|
/* Features available only for STM32F469_479xx devices */
|
||||||
|
#if defined(STM32F469_479xx)
|
||||||
|
void RCC_DSIClockSourceConfig(uint8_t RCC_ClockSource);
|
||||||
|
#endif /* STM32F469_479xx */
|
||||||
|
|
||||||
|
/* Features available only for STM32F412xG/STM32F446xx/STM32F469_479xx devices */
|
||||||
|
#if defined(STM32F412xG) || defined(STM32F446xx) || defined(STM32F469_479xx)
|
||||||
|
void RCC_48MHzClockSourceConfig(uint8_t RCC_ClockSource);
|
||||||
|
void RCC_SDIOClockSourceConfig(uint8_t RCC_ClockSource);
|
||||||
|
#endif /* STM32F412xG || STM32F446xx || STM32F469_479xx */
|
||||||
|
|
||||||
|
/* Features available only for STM32F446xx devices */
|
||||||
|
#if defined(STM32F446xx)
|
||||||
|
void RCC_AHB1ClockGatingCmd(uint32_t RCC_AHB1ClockGating, FunctionalState NewState);
|
||||||
|
void RCC_SPDIFRXClockSourceConfig(uint8_t RCC_ClockSource);
|
||||||
|
void RCC_CECClockSourceConfig(uint8_t RCC_ClockSource);
|
||||||
|
#endif /* STM32F446xx */
|
||||||
|
|
||||||
|
/* Features available only for STM32F410xx/STM32F412xG/STM32F446xx devices */
|
||||||
|
#if defined(STM32F410xx) || defined(STM32F412xG) || defined(STM32F446xx)
|
||||||
|
void RCC_FMPI2C1ClockSourceConfig(uint32_t RCC_ClockSource);
|
||||||
|
#endif /* STM32F410xx || STM32F412xG || STM32F446xx */
|
||||||
|
|
||||||
|
/* Features available only for STM32F410xx devices */
|
||||||
|
#if defined(STM32F410xx)
|
||||||
|
void RCC_LPTIM1ClockSourceConfig(uint32_t RCC_ClockSource);
|
||||||
|
|
||||||
|
void RCC_MCO1Cmd(FunctionalState NewState);
|
||||||
|
void RCC_MCO2Cmd(FunctionalState NewState);
|
||||||
|
#endif /* STM32F410xx */
|
||||||
|
|
||||||
|
#if defined(STM32F412xG)
|
||||||
|
void RCC_DFSDM1CLKConfig(uint32_t RCC_DFSDM1CLKSource);
|
||||||
|
void RCC_DFSDM1ACLKConfig(uint32_t RCC_DFSDM1ACLKSource);
|
||||||
|
#endif /* STM32F412xG */
|
||||||
|
/* Interrupts and flags management functions **********************************/
|
||||||
|
void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState);
|
||||||
|
FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG);
|
||||||
|
void RCC_ClearFlag(void);
|
||||||
|
ITStatus RCC_GetITStatus(uint8_t RCC_IT);
|
||||||
|
void RCC_ClearITPendingBit(uint8_t RCC_IT);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __STM32F4xx_RCC_H */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,431 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f4xx_usart.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @version V1.7.1
|
||||||
|
* @date 20-May-2016
|
||||||
|
* @brief This file contains all the functions prototypes for the USART
|
||||||
|
* firmware library.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
|
||||||
|
*
|
||||||
|
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.st.com/software_license_agreement_liberty_v2
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __STM32F4xx_USART_H
|
||||||
|
#define __STM32F4xx_USART_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32F4xx_StdPeriph_Driver
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup USART
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USART Init Structure definition
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t USART_BaudRate; /*!< This member configures the USART communication baud rate.
|
||||||
|
The baud rate is computed using the following formula:
|
||||||
|
- IntegerDivider = ((PCLKx) / (8 * (OVR8+1) * (USART_InitStruct->USART_BaudRate)))
|
||||||
|
- FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 8 * (OVR8+1)) + 0.5
|
||||||
|
Where OVR8 is the "oversampling by 8 mode" configuration bit in the CR1 register. */
|
||||||
|
|
||||||
|
uint16_t USART_WordLength; /*!< Specifies the number of data bits transmitted or received in a frame.
|
||||||
|
This parameter can be a value of @ref USART_Word_Length */
|
||||||
|
|
||||||
|
uint16_t USART_StopBits; /*!< Specifies the number of stop bits transmitted.
|
||||||
|
This parameter can be a value of @ref USART_Stop_Bits */
|
||||||
|
|
||||||
|
uint16_t USART_Parity; /*!< Specifies the parity mode.
|
||||||
|
This parameter can be a value of @ref USART_Parity
|
||||||
|
@note When parity is enabled, the computed parity is inserted
|
||||||
|
at the MSB position of the transmitted data (9th bit when
|
||||||
|
the word length is set to 9 data bits; 8th bit when the
|
||||||
|
word length is set to 8 data bits). */
|
||||||
|
|
||||||
|
uint16_t USART_Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled.
|
||||||
|
This parameter can be a value of @ref USART_Mode */
|
||||||
|
|
||||||
|
uint16_t USART_HardwareFlowControl; /*!< Specifies wether the hardware flow control mode is enabled
|
||||||
|
or disabled.
|
||||||
|
This parameter can be a value of @ref USART_Hardware_Flow_Control */
|
||||||
|
} USART_InitTypeDef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USART Clock Init Structure definition
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
|
||||||
|
uint16_t USART_Clock; /*!< Specifies whether the USART clock is enabled or disabled.
|
||||||
|
This parameter can be a value of @ref USART_Clock */
|
||||||
|
|
||||||
|
uint16_t USART_CPOL; /*!< Specifies the steady state of the serial clock.
|
||||||
|
This parameter can be a value of @ref USART_Clock_Polarity */
|
||||||
|
|
||||||
|
uint16_t USART_CPHA; /*!< Specifies the clock transition on which the bit capture is made.
|
||||||
|
This parameter can be a value of @ref USART_Clock_Phase */
|
||||||
|
|
||||||
|
uint16_t USART_LastBit; /*!< Specifies whether the clock pulse corresponding to the last transmitted
|
||||||
|
data bit (MSB) has to be output on the SCLK pin in synchronous mode.
|
||||||
|
This parameter can be a value of @ref USART_Last_Bit */
|
||||||
|
} USART_ClockInitTypeDef;
|
||||||
|
|
||||||
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
|
||||||
|
/** @defgroup USART_Exported_Constants
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define IS_USART_ALL_PERIPH(PERIPH) (((PERIPH) == USART1) || \
|
||||||
|
((PERIPH) == USART2) || \
|
||||||
|
((PERIPH) == USART3) || \
|
||||||
|
((PERIPH) == UART4) || \
|
||||||
|
((PERIPH) == UART5) || \
|
||||||
|
((PERIPH) == USART6) || \
|
||||||
|
((PERIPH) == UART7) || \
|
||||||
|
((PERIPH) == UART8))
|
||||||
|
|
||||||
|
#define IS_USART_1236_PERIPH(PERIPH) (((PERIPH) == USART1) || \
|
||||||
|
((PERIPH) == USART2) || \
|
||||||
|
((PERIPH) == USART3) || \
|
||||||
|
((PERIPH) == USART6))
|
||||||
|
|
||||||
|
/** @defgroup USART_Word_Length
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define USART_WordLength_8b ((uint16_t)0x0000)
|
||||||
|
#define USART_WordLength_9b ((uint16_t)0x1000)
|
||||||
|
|
||||||
|
#define IS_USART_WORD_LENGTH(LENGTH) (((LENGTH) == USART_WordLength_8b) || \
|
||||||
|
((LENGTH) == USART_WordLength_9b))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USART_Stop_Bits
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define USART_StopBits_1 ((uint16_t)0x0000)
|
||||||
|
#define USART_StopBits_0_5 ((uint16_t)0x1000)
|
||||||
|
#define USART_StopBits_2 ((uint16_t)0x2000)
|
||||||
|
#define USART_StopBits_1_5 ((uint16_t)0x3000)
|
||||||
|
#define IS_USART_STOPBITS(STOPBITS) (((STOPBITS) == USART_StopBits_1) || \
|
||||||
|
((STOPBITS) == USART_StopBits_0_5) || \
|
||||||
|
((STOPBITS) == USART_StopBits_2) || \
|
||||||
|
((STOPBITS) == USART_StopBits_1_5))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USART_Parity
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define USART_Parity_No ((uint16_t)0x0000)
|
||||||
|
#define USART_Parity_Even ((uint16_t)0x0400)
|
||||||
|
#define USART_Parity_Odd ((uint16_t)0x0600)
|
||||||
|
#define IS_USART_PARITY(PARITY) (((PARITY) == USART_Parity_No) || \
|
||||||
|
((PARITY) == USART_Parity_Even) || \
|
||||||
|
((PARITY) == USART_Parity_Odd))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USART_Mode
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define USART_Mode_Rx ((uint16_t)0x0004)
|
||||||
|
#define USART_Mode_Tx ((uint16_t)0x0008)
|
||||||
|
#define IS_USART_MODE(MODE) ((((MODE) & (uint16_t)0xFFF3) == 0x00) && ((MODE) != (uint16_t)0x00))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USART_Hardware_Flow_Control
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define USART_HardwareFlowControl_None ((uint16_t)0x0000)
|
||||||
|
#define USART_HardwareFlowControl_RTS ((uint16_t)0x0100)
|
||||||
|
#define USART_HardwareFlowControl_CTS ((uint16_t)0x0200)
|
||||||
|
#define USART_HardwareFlowControl_RTS_CTS ((uint16_t)0x0300)
|
||||||
|
#define IS_USART_HARDWARE_FLOW_CONTROL(CONTROL)\
|
||||||
|
(((CONTROL) == USART_HardwareFlowControl_None) || \
|
||||||
|
((CONTROL) == USART_HardwareFlowControl_RTS) || \
|
||||||
|
((CONTROL) == USART_HardwareFlowControl_CTS) || \
|
||||||
|
((CONTROL) == USART_HardwareFlowControl_RTS_CTS))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USART_Clock
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define USART_Clock_Disable ((uint16_t)0x0000)
|
||||||
|
#define USART_Clock_Enable ((uint16_t)0x0800)
|
||||||
|
#define IS_USART_CLOCK(CLOCK) (((CLOCK) == USART_Clock_Disable) || \
|
||||||
|
((CLOCK) == USART_Clock_Enable))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USART_Clock_Polarity
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define USART_CPOL_Low ((uint16_t)0x0000)
|
||||||
|
#define USART_CPOL_High ((uint16_t)0x0400)
|
||||||
|
#define IS_USART_CPOL(CPOL) (((CPOL) == USART_CPOL_Low) || ((CPOL) == USART_CPOL_High))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USART_Clock_Phase
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define USART_CPHA_1Edge ((uint16_t)0x0000)
|
||||||
|
#define USART_CPHA_2Edge ((uint16_t)0x0200)
|
||||||
|
#define IS_USART_CPHA(CPHA) (((CPHA) == USART_CPHA_1Edge) || ((CPHA) == USART_CPHA_2Edge))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USART_Last_Bit
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define USART_LastBit_Disable ((uint16_t)0x0000)
|
||||||
|
#define USART_LastBit_Enable ((uint16_t)0x0100)
|
||||||
|
#define IS_USART_LASTBIT(LASTBIT) (((LASTBIT) == USART_LastBit_Disable) || \
|
||||||
|
((LASTBIT) == USART_LastBit_Enable))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USART_Interrupt_definition
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define USART_IT_PE ((uint16_t)0x0028)
|
||||||
|
#define USART_IT_TXE ((uint16_t)0x0727)
|
||||||
|
#define USART_IT_TC ((uint16_t)0x0626)
|
||||||
|
#define USART_IT_RXNE ((uint16_t)0x0525)
|
||||||
|
#define USART_IT_ORE_RX ((uint16_t)0x0325) /* In case interrupt is generated if the RXNEIE bit is set */
|
||||||
|
#define USART_IT_IDLE ((uint16_t)0x0424)
|
||||||
|
#define USART_IT_LBD ((uint16_t)0x0846)
|
||||||
|
#define USART_IT_CTS ((uint16_t)0x096A)
|
||||||
|
#define USART_IT_ERR ((uint16_t)0x0060)
|
||||||
|
#define USART_IT_ORE_ER ((uint16_t)0x0360) /* In case interrupt is generated if the EIE bit is set */
|
||||||
|
#define USART_IT_NE ((uint16_t)0x0260)
|
||||||
|
#define USART_IT_FE ((uint16_t)0x0160)
|
||||||
|
|
||||||
|
/** @defgroup USART_Legacy
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define USART_IT_ORE USART_IT_ORE_ER
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define IS_USART_CONFIG_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \
|
||||||
|
((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \
|
||||||
|
((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \
|
||||||
|
((IT) == USART_IT_CTS) || ((IT) == USART_IT_ERR))
|
||||||
|
#define IS_USART_GET_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \
|
||||||
|
((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \
|
||||||
|
((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \
|
||||||
|
((IT) == USART_IT_CTS) || ((IT) == USART_IT_ORE) || \
|
||||||
|
((IT) == USART_IT_ORE_RX) || ((IT) == USART_IT_ORE_ER) || \
|
||||||
|
((IT) == USART_IT_NE) || ((IT) == USART_IT_FE))
|
||||||
|
#define IS_USART_CLEAR_IT(IT) (((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \
|
||||||
|
((IT) == USART_IT_LBD) || ((IT) == USART_IT_CTS))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USART_DMA_Requests
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define USART_DMAReq_Tx ((uint16_t)0x0080)
|
||||||
|
#define USART_DMAReq_Rx ((uint16_t)0x0040)
|
||||||
|
#define IS_USART_DMAREQ(DMAREQ) ((((DMAREQ) & (uint16_t)0xFF3F) == 0x00) && ((DMAREQ) != (uint16_t)0x00))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USART_WakeUp_methods
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define USART_WakeUp_IdleLine ((uint16_t)0x0000)
|
||||||
|
#define USART_WakeUp_AddressMark ((uint16_t)0x0800)
|
||||||
|
#define IS_USART_WAKEUP(WAKEUP) (((WAKEUP) == USART_WakeUp_IdleLine) || \
|
||||||
|
((WAKEUP) == USART_WakeUp_AddressMark))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USART_LIN_Break_Detection_Length
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define USART_LINBreakDetectLength_10b ((uint16_t)0x0000)
|
||||||
|
#define USART_LINBreakDetectLength_11b ((uint16_t)0x0020)
|
||||||
|
#define IS_USART_LIN_BREAK_DETECT_LENGTH(LENGTH) \
|
||||||
|
(((LENGTH) == USART_LINBreakDetectLength_10b) || \
|
||||||
|
((LENGTH) == USART_LINBreakDetectLength_11b))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USART_IrDA_Low_Power
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define USART_IrDAMode_LowPower ((uint16_t)0x0004)
|
||||||
|
#define USART_IrDAMode_Normal ((uint16_t)0x0000)
|
||||||
|
#define IS_USART_IRDA_MODE(MODE) (((MODE) == USART_IrDAMode_LowPower) || \
|
||||||
|
((MODE) == USART_IrDAMode_Normal))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USART_Flags
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define USART_FLAG_CTS ((uint16_t)0x0200)
|
||||||
|
#define USART_FLAG_LBD ((uint16_t)0x0100)
|
||||||
|
#define USART_FLAG_TXE ((uint16_t)0x0080)
|
||||||
|
#define USART_FLAG_TC ((uint16_t)0x0040)
|
||||||
|
#define USART_FLAG_RXNE ((uint16_t)0x0020)
|
||||||
|
#define USART_FLAG_IDLE ((uint16_t)0x0010)
|
||||||
|
#define USART_FLAG_ORE ((uint16_t)0x0008)
|
||||||
|
#define USART_FLAG_NE ((uint16_t)0x0004)
|
||||||
|
#define USART_FLAG_FE ((uint16_t)0x0002)
|
||||||
|
#define USART_FLAG_PE ((uint16_t)0x0001)
|
||||||
|
#define IS_USART_FLAG(FLAG) (((FLAG) == USART_FLAG_PE) || ((FLAG) == USART_FLAG_TXE) || \
|
||||||
|
((FLAG) == USART_FLAG_TC) || ((FLAG) == USART_FLAG_RXNE) || \
|
||||||
|
((FLAG) == USART_FLAG_IDLE) || ((FLAG) == USART_FLAG_LBD) || \
|
||||||
|
((FLAG) == USART_FLAG_CTS) || ((FLAG) == USART_FLAG_ORE) || \
|
||||||
|
((FLAG) == USART_FLAG_NE) || ((FLAG) == USART_FLAG_FE))
|
||||||
|
|
||||||
|
#define IS_USART_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0xFC9F) == 0x00) && ((FLAG) != (uint16_t)0x00))
|
||||||
|
|
||||||
|
#define IS_USART_BAUDRATE(BAUDRATE) (((BAUDRATE) > 0) && ((BAUDRATE) < 7500001))
|
||||||
|
#define IS_USART_ADDRESS(ADDRESS) ((ADDRESS) <= 0xF)
|
||||||
|
#define IS_USART_DATA(DATA) ((DATA) <= 0x1FF)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Function used to set the USART configuration to the default reset state ***/
|
||||||
|
void USART_DeInit(USART_TypeDef* USARTx);
|
||||||
|
|
||||||
|
/* Initialization and Configuration functions *********************************/
|
||||||
|
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
|
||||||
|
void USART_StructInit(USART_InitTypeDef* USART_InitStruct);
|
||||||
|
void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct);
|
||||||
|
void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct);
|
||||||
|
void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);
|
||||||
|
void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler);
|
||||||
|
void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState);
|
||||||
|
void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState);
|
||||||
|
|
||||||
|
/* Data transfers functions ***************************************************/
|
||||||
|
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
|
||||||
|
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
|
||||||
|
|
||||||
|
/* Multi-Processor Communication functions ************************************/
|
||||||
|
void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address);
|
||||||
|
void USART_WakeUpConfig(USART_TypeDef* USARTx, uint16_t USART_WakeUp);
|
||||||
|
void USART_ReceiverWakeUpCmd(USART_TypeDef* USARTx, FunctionalState NewState);
|
||||||
|
|
||||||
|
/* LIN mode functions *********************************************************/
|
||||||
|
void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint16_t USART_LINBreakDetectLength);
|
||||||
|
void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState);
|
||||||
|
void USART_SendBreak(USART_TypeDef* USARTx);
|
||||||
|
|
||||||
|
/* Half-duplex mode function **************************************************/
|
||||||
|
void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState);
|
||||||
|
|
||||||
|
/* Smartcard mode functions ***************************************************/
|
||||||
|
void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState);
|
||||||
|
void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState);
|
||||||
|
void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime);
|
||||||
|
|
||||||
|
/* IrDA mode functions ********************************************************/
|
||||||
|
void USART_IrDAConfig(USART_TypeDef* USARTx, uint16_t USART_IrDAMode);
|
||||||
|
void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState);
|
||||||
|
|
||||||
|
/* DMA transfers management functions *****************************************/
|
||||||
|
void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState);
|
||||||
|
|
||||||
|
/* Interrupts and flags management functions **********************************/
|
||||||
|
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);
|
||||||
|
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
|
||||||
|
void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);
|
||||||
|
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);
|
||||||
|
void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __STM32F4xx_USART_H */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
@@ -0,0 +1,249 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file misc.c
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @version V1.7.1
|
||||||
|
* @date 20-May-2016
|
||||||
|
* @brief This file provides all the miscellaneous firmware functions (add-on
|
||||||
|
* to CMSIS functions).
|
||||||
|
*
|
||||||
|
* @verbatim
|
||||||
|
*
|
||||||
|
* ===================================================================
|
||||||
|
* How to configure Interrupts using driver
|
||||||
|
* ===================================================================
|
||||||
|
*
|
||||||
|
* This section provide functions allowing to configure the NVIC interrupts (IRQ).
|
||||||
|
* The Cortex-M4 exceptions are managed by CMSIS functions.
|
||||||
|
*
|
||||||
|
* 1. Configure the NVIC Priority Grouping using NVIC_PriorityGroupConfig()
|
||||||
|
* function according to the following table.
|
||||||
|
|
||||||
|
* The table below gives the allowed values of the pre-emption priority and subpriority according
|
||||||
|
* to the Priority Grouping configuration performed by NVIC_PriorityGroupConfig function
|
||||||
|
* ==========================================================================================================================
|
||||||
|
* NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description
|
||||||
|
* ==========================================================================================================================
|
||||||
|
* NVIC_PriorityGroup_0 | 0 | 0-15 | 0 bits for pre-emption priority
|
||||||
|
* | | | 4 bits for subpriority
|
||||||
|
* --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
* NVIC_PriorityGroup_1 | 0-1 | 0-7 | 1 bits for pre-emption priority
|
||||||
|
* | | | 3 bits for subpriority
|
||||||
|
* --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
* NVIC_PriorityGroup_2 | 0-3 | 0-3 | 2 bits for pre-emption priority
|
||||||
|
* | | | 2 bits for subpriority
|
||||||
|
* --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
* NVIC_PriorityGroup_3 | 0-7 | 0-1 | 3 bits for pre-emption priority
|
||||||
|
* | | | 1 bits for subpriority
|
||||||
|
* --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
* NVIC_PriorityGroup_4 | 0-15 | 0 | 4 bits for pre-emption priority
|
||||||
|
* | | | 0 bits for subpriority
|
||||||
|
* ==========================================================================================================================
|
||||||
|
*
|
||||||
|
* 2. Enable and Configure the priority of the selected IRQ Channels using NVIC_Init()
|
||||||
|
*
|
||||||
|
* @note When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible.
|
||||||
|
* The pending IRQ priority will be managed only by the subpriority.
|
||||||
|
*
|
||||||
|
* @note IRQ priority order (sorted by highest to lowest priority):
|
||||||
|
* - Lowest pre-emption priority
|
||||||
|
* - Lowest subpriority
|
||||||
|
* - Lowest hardware priority (IRQ number)
|
||||||
|
*
|
||||||
|
* @endverbatim
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
|
||||||
|
*
|
||||||
|
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.st.com/software_license_agreement_liberty_v2
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32F4xx_StdPeriph_Driver
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup MISC
|
||||||
|
* @brief MISC driver modules
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
|
/* Private define ------------------------------------------------------------*/
|
||||||
|
#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000)
|
||||||
|
|
||||||
|
/* Private macro -------------------------------------------------------------*/
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
|
||||||
|
/** @defgroup MISC_Private_Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configures the priority grouping: pre-emption priority and subpriority.
|
||||||
|
* @param NVIC_PriorityGroup: specifies the priority grouping bits length.
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority
|
||||||
|
* 4 bits for subpriority
|
||||||
|
* @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority
|
||||||
|
* 3 bits for subpriority
|
||||||
|
* @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority
|
||||||
|
* 2 bits for subpriority
|
||||||
|
* @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority
|
||||||
|
* 1 bits for subpriority
|
||||||
|
* @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority
|
||||||
|
* 0 bits for subpriority
|
||||||
|
* @note When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible.
|
||||||
|
* The pending IRQ priority will be managed only by the subpriority.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
|
||||||
|
|
||||||
|
/* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */
|
||||||
|
SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes the NVIC peripheral according to the specified
|
||||||
|
* parameters in the NVIC_InitStruct.
|
||||||
|
* @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig()
|
||||||
|
* function should be called before.
|
||||||
|
* @param NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains
|
||||||
|
* the configuration information for the specified NVIC peripheral.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
|
||||||
|
{
|
||||||
|
uint8_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F;
|
||||||
|
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd));
|
||||||
|
assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority));
|
||||||
|
assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority));
|
||||||
|
|
||||||
|
if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE)
|
||||||
|
{
|
||||||
|
/* Compute the Corresponding IRQ Priority --------------------------------*/
|
||||||
|
tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08;
|
||||||
|
tmppre = (0x4 - tmppriority);
|
||||||
|
tmpsub = tmpsub >> tmppriority;
|
||||||
|
|
||||||
|
tmppriority = NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre;
|
||||||
|
tmppriority |= (uint8_t)(NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub);
|
||||||
|
|
||||||
|
tmppriority = tmppriority << 0x04;
|
||||||
|
|
||||||
|
NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority;
|
||||||
|
|
||||||
|
/* Enable the Selected IRQ Channels --------------------------------------*/
|
||||||
|
NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
|
||||||
|
(uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Disable the Selected IRQ Channels -------------------------------------*/
|
||||||
|
NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
|
||||||
|
(uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the vector table location and Offset.
|
||||||
|
* @param NVIC_VectTab: specifies if the vector table is in RAM or FLASH memory.
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg NVIC_VectTab_RAM: Vector Table in internal SRAM.
|
||||||
|
* @arg NVIC_VectTab_FLASH: Vector Table in internal FLASH.
|
||||||
|
* @param Offset: Vector Table base offset field. This value must be a multiple of 0x200.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_NVIC_VECTTAB(NVIC_VectTab));
|
||||||
|
assert_param(IS_NVIC_OFFSET(Offset));
|
||||||
|
|
||||||
|
SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Selects the condition for the system to enter low power mode.
|
||||||
|
* @param LowPowerMode: Specifies the new mode for the system to enter low power mode.
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg NVIC_LP_SEVONPEND: Low Power SEV on Pend.
|
||||||
|
* @arg NVIC_LP_SLEEPDEEP: Low Power DEEPSLEEP request.
|
||||||
|
* @arg NVIC_LP_SLEEPONEXIT: Low Power Sleep on Exit.
|
||||||
|
* @param NewState: new state of LP condition. This parameter can be: ENABLE or DISABLE.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_NVIC_LP(LowPowerMode));
|
||||||
|
assert_param(IS_FUNCTIONAL_STATE(NewState));
|
||||||
|
|
||||||
|
if (NewState != DISABLE)
|
||||||
|
{
|
||||||
|
SCB->SCR |= LowPowerMode;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SCB->SCR &= (uint32_t)(~(uint32_t)LowPowerMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configures the SysTick clock source.
|
||||||
|
* @param SysTick_CLKSource: specifies the SysTick clock source.
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source.
|
||||||
|
* @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));
|
||||||
|
if (SysTick_CLKSource == SysTick_CLKSource_HCLK)
|
||||||
|
{
|
||||||
|
SysTick->CTRL |= SysTick_CLKSource_HCLK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,714 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f4xx_dac.c
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @version V1.7.1
|
||||||
|
* @date 20-May-2016
|
||||||
|
* @brief This file provides firmware functions to manage the following
|
||||||
|
* functionalities of the Digital-to-Analog Converter (DAC) peripheral:
|
||||||
|
* + DAC channels configuration: trigger, output buffer, data format
|
||||||
|
* + DMA management
|
||||||
|
* + Interrupts and flags management
|
||||||
|
*
|
||||||
|
@verbatim
|
||||||
|
===============================================================================
|
||||||
|
##### DAC Peripheral features #####
|
||||||
|
===============================================================================
|
||||||
|
[..]
|
||||||
|
*** DAC Channels ***
|
||||||
|
====================
|
||||||
|
[..]
|
||||||
|
The device integrates two 12-bit Digital Analog Converters that can
|
||||||
|
be used independently or simultaneously (dual mode):
|
||||||
|
(#) DAC channel1 with DAC_OUT1 (PA4) as output
|
||||||
|
(#) DAC channel2 with DAC_OUT2 (PA5) as output
|
||||||
|
|
||||||
|
*** DAC Triggers ***
|
||||||
|
====================
|
||||||
|
[..]
|
||||||
|
Digital to Analog conversion can be non-triggered using DAC_Trigger_None
|
||||||
|
and DAC_OUT1/DAC_OUT2 is available once writing to DHRx register
|
||||||
|
using DAC_SetChannel1Data() / DAC_SetChannel2Data() functions.
|
||||||
|
[..]
|
||||||
|
Digital to Analog conversion can be triggered by:
|
||||||
|
(#) External event: EXTI Line 9 (any GPIOx_Pin9) using DAC_Trigger_Ext_IT9.
|
||||||
|
The used pin (GPIOx_Pin9) must be configured in input mode.
|
||||||
|
|
||||||
|
(#) Timers TRGO: TIM2, TIM4, TIM5, TIM6, TIM7 and TIM8
|
||||||
|
(DAC_Trigger_T2_TRGO, DAC_Trigger_T4_TRGO...)
|
||||||
|
The timer TRGO event should be selected using TIM_SelectOutputTrigger()
|
||||||
|
|
||||||
|
(#) Software using DAC_Trigger_Software
|
||||||
|
|
||||||
|
*** DAC Buffer mode feature ***
|
||||||
|
===============================
|
||||||
|
[..]
|
||||||
|
Each DAC channel integrates an output buffer that can be used to
|
||||||
|
reduce the output impedance, and to drive external loads directly
|
||||||
|
without having to add an external operational amplifier.
|
||||||
|
To enable, the output buffer use
|
||||||
|
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
|
||||||
|
[..]
|
||||||
|
(@) Refer to the device datasheet for more details about output
|
||||||
|
impedance value with and without output buffer.
|
||||||
|
|
||||||
|
*** DAC wave generation feature ***
|
||||||
|
===================================
|
||||||
|
[..]
|
||||||
|
Both DAC channels can be used to generate
|
||||||
|
(#) Noise wave using DAC_WaveGeneration_Noise
|
||||||
|
(#) Triangle wave using DAC_WaveGeneration_Triangle
|
||||||
|
|
||||||
|
-@- Wave generation can be disabled using DAC_WaveGeneration_None
|
||||||
|
|
||||||
|
*** DAC data format ***
|
||||||
|
=======================
|
||||||
|
[..]
|
||||||
|
The DAC data format can be:
|
||||||
|
(#) 8-bit right alignment using DAC_Align_8b_R
|
||||||
|
(#) 12-bit left alignment using DAC_Align_12b_L
|
||||||
|
(#) 12-bit right alignment using DAC_Align_12b_R
|
||||||
|
|
||||||
|
*** DAC data value to voltage correspondence ***
|
||||||
|
================================================
|
||||||
|
[..]
|
||||||
|
The analog output voltage on each DAC channel pin is determined
|
||||||
|
by the following equation:
|
||||||
|
DAC_OUTx = VREF+ * DOR / 4095
|
||||||
|
with DOR is the Data Output Register
|
||||||
|
VEF+ is the input voltage reference (refer to the device datasheet)
|
||||||
|
e.g. To set DAC_OUT1 to 0.7V, use
|
||||||
|
DAC_SetChannel1Data(DAC_Align_12b_R, 868);
|
||||||
|
Assuming that VREF+ = 3.3V, DAC_OUT1 = (3.3 * 868) / 4095 = 0.7V
|
||||||
|
|
||||||
|
*** DMA requests ***
|
||||||
|
=====================
|
||||||
|
[..]
|
||||||
|
A DMA1 request can be generated when an external trigger (but not
|
||||||
|
a software trigger) occurs if DMA1 requests are enabled using
|
||||||
|
DAC_DMACmd()
|
||||||
|
[..]
|
||||||
|
DMA1 requests are mapped as following:
|
||||||
|
(#) DAC channel1 : mapped on DMA1 Stream5 channel7 which must be
|
||||||
|
already configured
|
||||||
|
(#) DAC channel2 : mapped on DMA1 Stream6 channel7 which must be
|
||||||
|
already configured
|
||||||
|
|
||||||
|
|
||||||
|
##### How to use this driver #####
|
||||||
|
===============================================================================
|
||||||
|
[..]
|
||||||
|
(+) DAC APB clock must be enabled to get write access to DAC
|
||||||
|
registers using
|
||||||
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE)
|
||||||
|
(+) Configure DAC_OUTx (DAC_OUT1: PA4, DAC_OUT2: PA5) in analog mode.
|
||||||
|
(+) Configure the DAC channel using DAC_Init() function
|
||||||
|
(+) Enable the DAC channel using DAC_Cmd() function
|
||||||
|
|
||||||
|
@endverbatim
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
|
||||||
|
*
|
||||||
|
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.st.com/software_license_agreement_liberty_v2
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "stm32f4xx_dac.h"
|
||||||
|
#include "stm32f4xx_rcc.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32F4xx_StdPeriph_Driver
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup DAC
|
||||||
|
* @brief DAC driver modules
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
|
/* Private define ------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* CR register Mask */
|
||||||
|
#define CR_CLEAR_MASK ((uint32_t)0x00000FFE)
|
||||||
|
|
||||||
|
/* DAC Dual Channels SWTRIG masks */
|
||||||
|
#define DUAL_SWTRIG_SET ((uint32_t)0x00000003)
|
||||||
|
#define DUAL_SWTRIG_RESET ((uint32_t)0xFFFFFFFC)
|
||||||
|
|
||||||
|
/* DHR registers offsets */
|
||||||
|
#define DHR12R1_OFFSET ((uint32_t)0x00000008)
|
||||||
|
#define DHR12R2_OFFSET ((uint32_t)0x00000014)
|
||||||
|
#define DHR12RD_OFFSET ((uint32_t)0x00000020)
|
||||||
|
|
||||||
|
/* DOR register offset */
|
||||||
|
#define DOR_OFFSET ((uint32_t)0x0000002C)
|
||||||
|
|
||||||
|
/* Private macro -------------------------------------------------------------*/
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
|
||||||
|
/** @defgroup DAC_Private_Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup DAC_Group1 DAC channels configuration
|
||||||
|
* @brief DAC channels configuration: trigger, output buffer, data format
|
||||||
|
*
|
||||||
|
@verbatim
|
||||||
|
===============================================================================
|
||||||
|
##### DAC channels configuration: trigger, output buffer, data format #####
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
@endverbatim
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Deinitializes the DAC peripheral registers to their default reset values.
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void DAC_DeInit(void)
|
||||||
|
{
|
||||||
|
/* Enable DAC reset state */
|
||||||
|
RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, ENABLE);
|
||||||
|
/* Release DAC from reset state */
|
||||||
|
RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, DISABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes the DAC peripheral according to the specified parameters
|
||||||
|
* in the DAC_InitStruct.
|
||||||
|
* @param DAC_Channel: the selected DAC channel.
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg DAC_Channel_1: DAC Channel1 selected
|
||||||
|
* @arg DAC_Channel_2: DAC Channel2 selected
|
||||||
|
* @param DAC_InitStruct: pointer to a DAC_InitTypeDef structure that contains
|
||||||
|
* the configuration information for the specified DAC channel.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct)
|
||||||
|
{
|
||||||
|
uint32_t tmpreg1 = 0, tmpreg2 = 0;
|
||||||
|
|
||||||
|
/* Check the DAC parameters */
|
||||||
|
assert_param(IS_DAC_TRIGGER(DAC_InitStruct->DAC_Trigger));
|
||||||
|
assert_param(IS_DAC_GENERATE_WAVE(DAC_InitStruct->DAC_WaveGeneration));
|
||||||
|
assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude));
|
||||||
|
assert_param(IS_DAC_OUTPUT_BUFFER_STATE(DAC_InitStruct->DAC_OutputBuffer));
|
||||||
|
|
||||||
|
/*---------------------------- DAC CR Configuration --------------------------*/
|
||||||
|
/* Get the DAC CR value */
|
||||||
|
tmpreg1 = DAC->CR;
|
||||||
|
/* Clear BOFFx, TENx, TSELx, WAVEx and MAMPx bits */
|
||||||
|
tmpreg1 &= ~(CR_CLEAR_MASK << DAC_Channel);
|
||||||
|
/* Configure for the selected DAC channel: buffer output, trigger,
|
||||||
|
wave generation, mask/amplitude for wave generation */
|
||||||
|
/* Set TSELx and TENx bits according to DAC_Trigger value */
|
||||||
|
/* Set WAVEx bits according to DAC_WaveGeneration value */
|
||||||
|
/* Set MAMPx bits according to DAC_LFSRUnmask_TriangleAmplitude value */
|
||||||
|
/* Set BOFFx bit according to DAC_OutputBuffer value */
|
||||||
|
tmpreg2 = (DAC_InitStruct->DAC_Trigger | DAC_InitStruct->DAC_WaveGeneration |
|
||||||
|
DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude | \
|
||||||
|
DAC_InitStruct->DAC_OutputBuffer);
|
||||||
|
/* Calculate CR register value depending on DAC_Channel */
|
||||||
|
tmpreg1 |= tmpreg2 << DAC_Channel;
|
||||||
|
/* Write to DAC CR */
|
||||||
|
DAC->CR = tmpreg1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Fills each DAC_InitStruct member with its default value.
|
||||||
|
* @param DAC_InitStruct: pointer to a DAC_InitTypeDef structure which will
|
||||||
|
* be initialized.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void DAC_StructInit(DAC_InitTypeDef* DAC_InitStruct)
|
||||||
|
{
|
||||||
|
/*--------------- Reset DAC init structure parameters values -----------------*/
|
||||||
|
/* Initialize the DAC_Trigger member */
|
||||||
|
DAC_InitStruct->DAC_Trigger = DAC_Trigger_None;
|
||||||
|
/* Initialize the DAC_WaveGeneration member */
|
||||||
|
DAC_InitStruct->DAC_WaveGeneration = DAC_WaveGeneration_None;
|
||||||
|
/* Initialize the DAC_LFSRUnmask_TriangleAmplitude member */
|
||||||
|
DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
|
||||||
|
/* Initialize the DAC_OutputBuffer member */
|
||||||
|
DAC_InitStruct->DAC_OutputBuffer = DAC_OutputBuffer_Enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables or disables the specified DAC channel.
|
||||||
|
* @param DAC_Channel: The selected DAC channel.
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg DAC_Channel_1: DAC Channel1 selected
|
||||||
|
* @arg DAC_Channel_2: DAC Channel2 selected
|
||||||
|
* @param NewState: new state of the DAC channel.
|
||||||
|
* This parameter can be: ENABLE or DISABLE.
|
||||||
|
* @note When the DAC channel is enabled the trigger source can no more be modified.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void DAC_Cmd(uint32_t DAC_Channel, FunctionalState NewState)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_DAC_CHANNEL(DAC_Channel));
|
||||||
|
assert_param(IS_FUNCTIONAL_STATE(NewState));
|
||||||
|
|
||||||
|
if (NewState != DISABLE)
|
||||||
|
{
|
||||||
|
/* Enable the selected DAC channel */
|
||||||
|
DAC->CR |= (DAC_CR_EN1 << DAC_Channel);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Disable the selected DAC channel */
|
||||||
|
DAC->CR &= (~(DAC_CR_EN1 << DAC_Channel));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables or disables the selected DAC channel software trigger.
|
||||||
|
* @param DAC_Channel: The selected DAC channel.
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg DAC_Channel_1: DAC Channel1 selected
|
||||||
|
* @arg DAC_Channel_2: DAC Channel2 selected
|
||||||
|
* @param NewState: new state of the selected DAC channel software trigger.
|
||||||
|
* This parameter can be: ENABLE or DISABLE.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void DAC_SoftwareTriggerCmd(uint32_t DAC_Channel, FunctionalState NewState)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_DAC_CHANNEL(DAC_Channel));
|
||||||
|
assert_param(IS_FUNCTIONAL_STATE(NewState));
|
||||||
|
|
||||||
|
if (NewState != DISABLE)
|
||||||
|
{
|
||||||
|
/* Enable software trigger for the selected DAC channel */
|
||||||
|
DAC->SWTRIGR |= (uint32_t)DAC_SWTRIGR_SWTRIG1 << (DAC_Channel >> 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Disable software trigger for the selected DAC channel */
|
||||||
|
DAC->SWTRIGR &= ~((uint32_t)DAC_SWTRIGR_SWTRIG1 << (DAC_Channel >> 4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables or disables simultaneously the two DAC channels software triggers.
|
||||||
|
* @param NewState: new state of the DAC channels software triggers.
|
||||||
|
* This parameter can be: ENABLE or DISABLE.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void DAC_DualSoftwareTriggerCmd(FunctionalState NewState)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_FUNCTIONAL_STATE(NewState));
|
||||||
|
|
||||||
|
if (NewState != DISABLE)
|
||||||
|
{
|
||||||
|
/* Enable software trigger for both DAC channels */
|
||||||
|
DAC->SWTRIGR |= DUAL_SWTRIG_SET;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Disable software trigger for both DAC channels */
|
||||||
|
DAC->SWTRIGR &= DUAL_SWTRIG_RESET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables or disables the selected DAC channel wave generation.
|
||||||
|
* @param DAC_Channel: The selected DAC channel.
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg DAC_Channel_1: DAC Channel1 selected
|
||||||
|
* @arg DAC_Channel_2: DAC Channel2 selected
|
||||||
|
* @param DAC_Wave: specifies the wave type to enable or disable.
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg DAC_Wave_Noise: noise wave generation
|
||||||
|
* @arg DAC_Wave_Triangle: triangle wave generation
|
||||||
|
* @param NewState: new state of the selected DAC channel wave generation.
|
||||||
|
* This parameter can be: ENABLE or DISABLE.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void DAC_WaveGenerationCmd(uint32_t DAC_Channel, uint32_t DAC_Wave, FunctionalState NewState)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_DAC_CHANNEL(DAC_Channel));
|
||||||
|
assert_param(IS_DAC_WAVE(DAC_Wave));
|
||||||
|
assert_param(IS_FUNCTIONAL_STATE(NewState));
|
||||||
|
|
||||||
|
if (NewState != DISABLE)
|
||||||
|
{
|
||||||
|
/* Enable the selected wave generation for the selected DAC channel */
|
||||||
|
DAC->CR |= DAC_Wave << DAC_Channel;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Disable the selected wave generation for the selected DAC channel */
|
||||||
|
DAC->CR &= ~(DAC_Wave << DAC_Channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the specified data holding register value for DAC channel1.
|
||||||
|
* @param DAC_Align: Specifies the data alignment for DAC channel1.
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg DAC_Align_8b_R: 8bit right data alignment selected
|
||||||
|
* @arg DAC_Align_12b_L: 12bit left data alignment selected
|
||||||
|
* @arg DAC_Align_12b_R: 12bit right data alignment selected
|
||||||
|
* @param Data: Data to be loaded in the selected data holding register.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data)
|
||||||
|
{
|
||||||
|
__IO uint32_t tmp = 0;
|
||||||
|
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_DAC_ALIGN(DAC_Align));
|
||||||
|
assert_param(IS_DAC_DATA(Data));
|
||||||
|
|
||||||
|
tmp = (uint32_t)DAC_BASE;
|
||||||
|
tmp += DHR12R1_OFFSET + DAC_Align;
|
||||||
|
|
||||||
|
/* Set the DAC channel1 selected data holding register */
|
||||||
|
*(__IO uint32_t *) tmp = Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the specified data holding register value for DAC channel2.
|
||||||
|
* @param DAC_Align: Specifies the data alignment for DAC channel2.
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg DAC_Align_8b_R: 8bit right data alignment selected
|
||||||
|
* @arg DAC_Align_12b_L: 12bit left data alignment selected
|
||||||
|
* @arg DAC_Align_12b_R: 12bit right data alignment selected
|
||||||
|
* @param Data: Data to be loaded in the selected data holding register.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void DAC_SetChannel2Data(uint32_t DAC_Align, uint16_t Data)
|
||||||
|
{
|
||||||
|
__IO uint32_t tmp = 0;
|
||||||
|
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_DAC_ALIGN(DAC_Align));
|
||||||
|
assert_param(IS_DAC_DATA(Data));
|
||||||
|
|
||||||
|
tmp = (uint32_t)DAC_BASE;
|
||||||
|
tmp += DHR12R2_OFFSET + DAC_Align;
|
||||||
|
|
||||||
|
/* Set the DAC channel2 selected data holding register */
|
||||||
|
*(__IO uint32_t *)tmp = Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the specified data holding register value for dual channel DAC.
|
||||||
|
* @param DAC_Align: Specifies the data alignment for dual channel DAC.
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg DAC_Align_8b_R: 8bit right data alignment selected
|
||||||
|
* @arg DAC_Align_12b_L: 12bit left data alignment selected
|
||||||
|
* @arg DAC_Align_12b_R: 12bit right data alignment selected
|
||||||
|
* @param Data2: Data for DAC Channel2 to be loaded in the selected data holding register.
|
||||||
|
* @param Data1: Data for DAC Channel1 to be loaded in the selected data holding register.
|
||||||
|
* @note In dual mode, a unique register access is required to write in both
|
||||||
|
* DAC channels at the same time.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void DAC_SetDualChannelData(uint32_t DAC_Align, uint16_t Data2, uint16_t Data1)
|
||||||
|
{
|
||||||
|
uint32_t data = 0, tmp = 0;
|
||||||
|
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_DAC_ALIGN(DAC_Align));
|
||||||
|
assert_param(IS_DAC_DATA(Data1));
|
||||||
|
assert_param(IS_DAC_DATA(Data2));
|
||||||
|
|
||||||
|
/* Calculate and set dual DAC data holding register value */
|
||||||
|
if (DAC_Align == DAC_Align_8b_R)
|
||||||
|
{
|
||||||
|
data = ((uint32_t)Data2 << 8) | Data1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data = ((uint32_t)Data2 << 16) | Data1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = (uint32_t)DAC_BASE;
|
||||||
|
tmp += DHR12RD_OFFSET + DAC_Align;
|
||||||
|
|
||||||
|
/* Set the dual DAC selected data holding register */
|
||||||
|
*(__IO uint32_t *)tmp = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the last data output value of the selected DAC channel.
|
||||||
|
* @param DAC_Channel: The selected DAC channel.
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg DAC_Channel_1: DAC Channel1 selected
|
||||||
|
* @arg DAC_Channel_2: DAC Channel2 selected
|
||||||
|
* @retval The selected DAC channel data output value.
|
||||||
|
*/
|
||||||
|
uint16_t DAC_GetDataOutputValue(uint32_t DAC_Channel)
|
||||||
|
{
|
||||||
|
__IO uint32_t tmp = 0;
|
||||||
|
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_DAC_CHANNEL(DAC_Channel));
|
||||||
|
|
||||||
|
tmp = (uint32_t) DAC_BASE ;
|
||||||
|
tmp += DOR_OFFSET + ((uint32_t)DAC_Channel >> 2);
|
||||||
|
|
||||||
|
/* Returns the DAC channel data output register value */
|
||||||
|
return (uint16_t) (*(__IO uint32_t*) tmp);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup DAC_Group2 DMA management functions
|
||||||
|
* @brief DMA management functions
|
||||||
|
*
|
||||||
|
@verbatim
|
||||||
|
===============================================================================
|
||||||
|
##### DMA management functions #####
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
@endverbatim
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables or disables the specified DAC channel DMA request.
|
||||||
|
* @note When enabled DMA1 is generated when an external trigger (EXTI Line9,
|
||||||
|
* TIM2, TIM4, TIM5, TIM6, TIM7 or TIM8 but not a software trigger) occurs.
|
||||||
|
* @param DAC_Channel: The selected DAC channel.
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg DAC_Channel_1: DAC Channel1 selected
|
||||||
|
* @arg DAC_Channel_2: DAC Channel2 selected
|
||||||
|
* @param NewState: new state of the selected DAC channel DMA request.
|
||||||
|
* This parameter can be: ENABLE or DISABLE.
|
||||||
|
* @note The DAC channel1 is mapped on DMA1 Stream 5 channel7 which must be
|
||||||
|
* already configured.
|
||||||
|
* @note The DAC channel2 is mapped on DMA1 Stream 6 channel7 which must be
|
||||||
|
* already configured.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void DAC_DMACmd(uint32_t DAC_Channel, FunctionalState NewState)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_DAC_CHANNEL(DAC_Channel));
|
||||||
|
assert_param(IS_FUNCTIONAL_STATE(NewState));
|
||||||
|
|
||||||
|
if (NewState != DISABLE)
|
||||||
|
{
|
||||||
|
/* Enable the selected DAC channel DMA request */
|
||||||
|
DAC->CR |= (DAC_CR_DMAEN1 << DAC_Channel);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Disable the selected DAC channel DMA request */
|
||||||
|
DAC->CR &= (~(DAC_CR_DMAEN1 << DAC_Channel));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup DAC_Group3 Interrupts and flags management functions
|
||||||
|
* @brief Interrupts and flags management functions
|
||||||
|
*
|
||||||
|
@verbatim
|
||||||
|
===============================================================================
|
||||||
|
##### Interrupts and flags management functions #####
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
@endverbatim
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables or disables the specified DAC interrupts.
|
||||||
|
* @param DAC_Channel: The selected DAC channel.
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg DAC_Channel_1: DAC Channel1 selected
|
||||||
|
* @arg DAC_Channel_2: DAC Channel2 selected
|
||||||
|
* @param DAC_IT: specifies the DAC interrupt sources to be enabled or disabled.
|
||||||
|
* This parameter can be the following values:
|
||||||
|
* @arg DAC_IT_DMAUDR: DMA underrun interrupt mask
|
||||||
|
* @note The DMA underrun occurs when a second external trigger arrives before the
|
||||||
|
* acknowledgement for the first external trigger is received (first request).
|
||||||
|
* @param NewState: new state of the specified DAC interrupts.
|
||||||
|
* This parameter can be: ENABLE or DISABLE.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void DAC_ITConfig(uint32_t DAC_Channel, uint32_t DAC_IT, FunctionalState NewState)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_DAC_CHANNEL(DAC_Channel));
|
||||||
|
assert_param(IS_FUNCTIONAL_STATE(NewState));
|
||||||
|
assert_param(IS_DAC_IT(DAC_IT));
|
||||||
|
|
||||||
|
if (NewState != DISABLE)
|
||||||
|
{
|
||||||
|
/* Enable the selected DAC interrupts */
|
||||||
|
DAC->CR |= (DAC_IT << DAC_Channel);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Disable the selected DAC interrupts */
|
||||||
|
DAC->CR &= (~(uint32_t)(DAC_IT << DAC_Channel));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks whether the specified DAC flag is set or not.
|
||||||
|
* @param DAC_Channel: The selected DAC channel.
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg DAC_Channel_1: DAC Channel1 selected
|
||||||
|
* @arg DAC_Channel_2: DAC Channel2 selected
|
||||||
|
* @param DAC_FLAG: specifies the flag to check.
|
||||||
|
* This parameter can be only of the following value:
|
||||||
|
* @arg DAC_FLAG_DMAUDR: DMA underrun flag
|
||||||
|
* @note The DMA underrun occurs when a second external trigger arrives before the
|
||||||
|
* acknowledgement for the first external trigger is received (first request).
|
||||||
|
* @retval The new state of DAC_FLAG (SET or RESET).
|
||||||
|
*/
|
||||||
|
FlagStatus DAC_GetFlagStatus(uint32_t DAC_Channel, uint32_t DAC_FLAG)
|
||||||
|
{
|
||||||
|
FlagStatus bitstatus = RESET;
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_DAC_CHANNEL(DAC_Channel));
|
||||||
|
assert_param(IS_DAC_FLAG(DAC_FLAG));
|
||||||
|
|
||||||
|
/* Check the status of the specified DAC flag */
|
||||||
|
if ((DAC->SR & (DAC_FLAG << DAC_Channel)) != (uint8_t)RESET)
|
||||||
|
{
|
||||||
|
/* DAC_FLAG is set */
|
||||||
|
bitstatus = SET;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* DAC_FLAG is reset */
|
||||||
|
bitstatus = RESET;
|
||||||
|
}
|
||||||
|
/* Return the DAC_FLAG status */
|
||||||
|
return bitstatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clears the DAC channel's pending flags.
|
||||||
|
* @param DAC_Channel: The selected DAC channel.
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg DAC_Channel_1: DAC Channel1 selected
|
||||||
|
* @arg DAC_Channel_2: DAC Channel2 selected
|
||||||
|
* @param DAC_FLAG: specifies the flag to clear.
|
||||||
|
* This parameter can be of the following value:
|
||||||
|
* @arg DAC_FLAG_DMAUDR: DMA underrun flag
|
||||||
|
* @note The DMA underrun occurs when a second external trigger arrives before the
|
||||||
|
* acknowledgement for the first external trigger is received (first request).
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void DAC_ClearFlag(uint32_t DAC_Channel, uint32_t DAC_FLAG)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_DAC_CHANNEL(DAC_Channel));
|
||||||
|
assert_param(IS_DAC_FLAG(DAC_FLAG));
|
||||||
|
|
||||||
|
/* Clear the selected DAC flags */
|
||||||
|
DAC->SR = (DAC_FLAG << DAC_Channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks whether the specified DAC interrupt has occurred or not.
|
||||||
|
* @param DAC_Channel: The selected DAC channel.
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg DAC_Channel_1: DAC Channel1 selected
|
||||||
|
* @arg DAC_Channel_2: DAC Channel2 selected
|
||||||
|
* @param DAC_IT: specifies the DAC interrupt source to check.
|
||||||
|
* This parameter can be the following values:
|
||||||
|
* @arg DAC_IT_DMAUDR: DMA underrun interrupt mask
|
||||||
|
* @note The DMA underrun occurs when a second external trigger arrives before the
|
||||||
|
* acknowledgement for the first external trigger is received (first request).
|
||||||
|
* @retval The new state of DAC_IT (SET or RESET).
|
||||||
|
*/
|
||||||
|
ITStatus DAC_GetITStatus(uint32_t DAC_Channel, uint32_t DAC_IT)
|
||||||
|
{
|
||||||
|
ITStatus bitstatus = RESET;
|
||||||
|
uint32_t enablestatus = 0;
|
||||||
|
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_DAC_CHANNEL(DAC_Channel));
|
||||||
|
assert_param(IS_DAC_IT(DAC_IT));
|
||||||
|
|
||||||
|
/* Get the DAC_IT enable bit status */
|
||||||
|
enablestatus = (DAC->CR & (DAC_IT << DAC_Channel)) ;
|
||||||
|
|
||||||
|
/* Check the status of the specified DAC interrupt */
|
||||||
|
if (((DAC->SR & (DAC_IT << DAC_Channel)) != (uint32_t)RESET) && enablestatus)
|
||||||
|
{
|
||||||
|
/* DAC_IT is set */
|
||||||
|
bitstatus = SET;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* DAC_IT is reset */
|
||||||
|
bitstatus = RESET;
|
||||||
|
}
|
||||||
|
/* Return the DAC_IT status */
|
||||||
|
return bitstatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clears the DAC channel's interrupt pending bits.
|
||||||
|
* @param DAC_Channel: The selected DAC channel.
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg DAC_Channel_1: DAC Channel1 selected
|
||||||
|
* @arg DAC_Channel_2: DAC Channel2 selected
|
||||||
|
* @param DAC_IT: specifies the DAC interrupt pending bit to clear.
|
||||||
|
* This parameter can be the following values:
|
||||||
|
* @arg DAC_IT_DMAUDR: DMA underrun interrupt mask
|
||||||
|
* @note The DMA underrun occurs when a second external trigger arrives before the
|
||||||
|
* acknowledgement for the first external trigger is received (first request).
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void DAC_ClearITPendingBit(uint32_t DAC_Channel, uint32_t DAC_IT)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_DAC_CHANNEL(DAC_Channel));
|
||||||
|
assert_param(IS_DAC_IT(DAC_IT));
|
||||||
|
|
||||||
|
/* Clear the selected DAC interrupt pending bits */
|
||||||
|
DAC->SR = (DAC_IT << DAC_Channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
@@ -0,0 +1,611 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f4xx_gpio.c
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @version V1.7.1
|
||||||
|
* @date 20-May-2016
|
||||||
|
* @brief This file provides firmware functions to manage the following
|
||||||
|
* functionalities of the GPIO peripheral:
|
||||||
|
* + Initialization and Configuration
|
||||||
|
* + GPIO Read and Write
|
||||||
|
* + GPIO Alternate functions configuration
|
||||||
|
*
|
||||||
|
@verbatim
|
||||||
|
===============================================================================
|
||||||
|
##### How to use this driver #####
|
||||||
|
===============================================================================
|
||||||
|
[..]
|
||||||
|
(#) Enable the GPIO AHB clock using the following function
|
||||||
|
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE);
|
||||||
|
|
||||||
|
(#) Configure the GPIO pin(s) using GPIO_Init()
|
||||||
|
Four possible configuration are available for each pin:
|
||||||
|
(++) Input: Floating, Pull-up, Pull-down.
|
||||||
|
(++) Output: Push-Pull (Pull-up, Pull-down or no Pull)
|
||||||
|
Open Drain (Pull-up, Pull-down or no Pull). In output mode, the speed
|
||||||
|
is configurable: 2 MHz, 25 MHz, 50 MHz or 100 MHz.
|
||||||
|
(++) Alternate Function: Push-Pull (Pull-up, Pull-down or no Pull) Open
|
||||||
|
Drain (Pull-up, Pull-down or no Pull).
|
||||||
|
(++) Analog: required mode when a pin is to be used as ADC channel or DAC
|
||||||
|
output.
|
||||||
|
|
||||||
|
(#) Peripherals alternate function:
|
||||||
|
(++) For ADC and DAC, configure the desired pin in analog mode using
|
||||||
|
GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AN;
|
||||||
|
(+++) For other peripherals (TIM, USART...):
|
||||||
|
(+++) Connect the pin to the desired peripherals' Alternate
|
||||||
|
Function (AF) using GPIO_PinAFConfig() function
|
||||||
|
(+++) Configure the desired pin in alternate function mode using
|
||||||
|
GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF
|
||||||
|
(+++) Select the type, pull-up/pull-down and output speed via
|
||||||
|
GPIO_PuPd, GPIO_OType and GPIO_Speed members
|
||||||
|
(+++) Call GPIO_Init() function
|
||||||
|
|
||||||
|
(#) To get the level of a pin configured in input mode use GPIO_ReadInputDataBit()
|
||||||
|
|
||||||
|
(#) To set/reset the level of a pin configured in output mode use
|
||||||
|
GPIO_SetBits()/GPIO_ResetBits()
|
||||||
|
|
||||||
|
(#) During and just after reset, the alternate functions are not
|
||||||
|
active and the GPIO pins are configured in input floating mode (except JTAG
|
||||||
|
pins).
|
||||||
|
|
||||||
|
(#) The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as general purpose
|
||||||
|
(PC14 and PC15, respectively) when the LSE oscillator is off. The LSE has
|
||||||
|
priority over the GPIO function.
|
||||||
|
|
||||||
|
(#) The HSE oscillator pins OSC_IN/OSC_OUT can be used as
|
||||||
|
general purpose PH0 and PH1, respectively, when the HSE oscillator is off.
|
||||||
|
The HSE has priority over the GPIO function.
|
||||||
|
|
||||||
|
@endverbatim
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
|
||||||
|
*
|
||||||
|
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.st.com/software_license_agreement_liberty_v2
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "stm32f4xx_gpio.h"
|
||||||
|
#include "stm32f4xx_rcc.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32F4xx_StdPeriph_Driver
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup GPIO
|
||||||
|
* @brief GPIO driver modules
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
|
/* Private define ------------------------------------------------------------*/
|
||||||
|
/* Private macro -------------------------------------------------------------*/
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
|
||||||
|
/** @defgroup GPIO_Private_Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup GPIO_Group1 Initialization and Configuration
|
||||||
|
* @brief Initialization and Configuration
|
||||||
|
*
|
||||||
|
@verbatim
|
||||||
|
===============================================================================
|
||||||
|
##### Initialization and Configuration #####
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
@endverbatim
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief De-initializes the GPIOx peripheral registers to their default reset values.
|
||||||
|
* @note By default, The GPIO pins are configured in input floating mode (except JTAG pins).
|
||||||
|
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices
|
||||||
|
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices.
|
||||||
|
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void GPIO_DeInit(GPIO_TypeDef* GPIOx)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
|
||||||
|
|
||||||
|
if (GPIOx == GPIOA)
|
||||||
|
{
|
||||||
|
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOA, ENABLE);
|
||||||
|
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOA, DISABLE);
|
||||||
|
}
|
||||||
|
else if (GPIOx == GPIOB)
|
||||||
|
{
|
||||||
|
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOB, ENABLE);
|
||||||
|
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOB, DISABLE);
|
||||||
|
}
|
||||||
|
else if (GPIOx == GPIOC)
|
||||||
|
{
|
||||||
|
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOC, ENABLE);
|
||||||
|
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOC, DISABLE);
|
||||||
|
}
|
||||||
|
else if (GPIOx == GPIOD)
|
||||||
|
{
|
||||||
|
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOD, ENABLE);
|
||||||
|
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOD, DISABLE);
|
||||||
|
}
|
||||||
|
else if (GPIOx == GPIOE)
|
||||||
|
{
|
||||||
|
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOE, ENABLE);
|
||||||
|
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOE, DISABLE);
|
||||||
|
}
|
||||||
|
else if (GPIOx == GPIOF)
|
||||||
|
{
|
||||||
|
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOF, ENABLE);
|
||||||
|
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOF, DISABLE);
|
||||||
|
}
|
||||||
|
else if (GPIOx == GPIOG)
|
||||||
|
{
|
||||||
|
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOG, ENABLE);
|
||||||
|
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOG, DISABLE);
|
||||||
|
}
|
||||||
|
else if (GPIOx == GPIOH)
|
||||||
|
{
|
||||||
|
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOH, ENABLE);
|
||||||
|
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOH, DISABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (GPIOx == GPIOI)
|
||||||
|
{
|
||||||
|
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOI, ENABLE);
|
||||||
|
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOI, DISABLE);
|
||||||
|
}
|
||||||
|
else if (GPIOx == GPIOJ)
|
||||||
|
{
|
||||||
|
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOJ, ENABLE);
|
||||||
|
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOJ, DISABLE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (GPIOx == GPIOK)
|
||||||
|
{
|
||||||
|
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOK, ENABLE);
|
||||||
|
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOK, DISABLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes the GPIOx peripheral according to the specified parameters in the GPIO_InitStruct.
|
||||||
|
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices
|
||||||
|
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices.
|
||||||
|
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices.
|
||||||
|
* @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that contains
|
||||||
|
* the configuration information for the specified GPIO peripheral.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
|
||||||
|
{
|
||||||
|
uint32_t pinpos = 0x00, pos = 0x00 , currentpin = 0x00;
|
||||||
|
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
|
||||||
|
assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));
|
||||||
|
assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));
|
||||||
|
assert_param(IS_GPIO_PUPD(GPIO_InitStruct->GPIO_PuPd));
|
||||||
|
|
||||||
|
/* ------------------------- Configure the port pins ---------------- */
|
||||||
|
/*-- GPIO Mode Configuration --*/
|
||||||
|
for (pinpos = 0x00; pinpos < 0x10; pinpos++)
|
||||||
|
{
|
||||||
|
pos = ((uint32_t)0x01) << pinpos;
|
||||||
|
/* Get the port pins position */
|
||||||
|
currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
|
||||||
|
|
||||||
|
if (currentpin == pos)
|
||||||
|
{
|
||||||
|
GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (pinpos * 2));
|
||||||
|
GPIOx->MODER |= (((uint32_t)GPIO_InitStruct->GPIO_Mode) << (pinpos * 2));
|
||||||
|
|
||||||
|
if ((GPIO_InitStruct->GPIO_Mode == GPIO_Mode_OUT) || (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_AF))
|
||||||
|
{
|
||||||
|
/* Check Speed mode parameters */
|
||||||
|
assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));
|
||||||
|
|
||||||
|
/* Speed mode configuration */
|
||||||
|
GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (pinpos * 2));
|
||||||
|
GPIOx->OSPEEDR |= ((uint32_t)(GPIO_InitStruct->GPIO_Speed) << (pinpos * 2));
|
||||||
|
|
||||||
|
/* Check Output mode parameters */
|
||||||
|
assert_param(IS_GPIO_OTYPE(GPIO_InitStruct->GPIO_OType));
|
||||||
|
|
||||||
|
/* Output mode configuration*/
|
||||||
|
GPIOx->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)pinpos)) ;
|
||||||
|
GPIOx->OTYPER |= (uint16_t)(((uint16_t)GPIO_InitStruct->GPIO_OType) << ((uint16_t)pinpos));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pull-up Pull down resistor configuration*/
|
||||||
|
GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)pinpos * 2));
|
||||||
|
GPIOx->PUPDR |= (((uint32_t)GPIO_InitStruct->GPIO_PuPd) << (pinpos * 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Fills each GPIO_InitStruct member with its default value.
|
||||||
|
* @param GPIO_InitStruct : pointer to a GPIO_InitTypeDef structure which will be initialized.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct)
|
||||||
|
{
|
||||||
|
/* Reset GPIO init structure parameters values */
|
||||||
|
GPIO_InitStruct->GPIO_Pin = GPIO_Pin_All;
|
||||||
|
GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN;
|
||||||
|
GPIO_InitStruct->GPIO_Speed = GPIO_Speed_2MHz;
|
||||||
|
GPIO_InitStruct->GPIO_OType = GPIO_OType_PP;
|
||||||
|
GPIO_InitStruct->GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Locks GPIO Pins configuration registers.
|
||||||
|
* @note The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR,
|
||||||
|
* GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH.
|
||||||
|
* @note The configuration of the locked GPIO pins can no longer be modified
|
||||||
|
* until the next reset.
|
||||||
|
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices
|
||||||
|
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices.
|
||||||
|
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices.
|
||||||
|
* @param GPIO_Pin: specifies the port bit to be locked.
|
||||||
|
* This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
|
||||||
|
{
|
||||||
|
__IO uint32_t tmp = 0x00010000;
|
||||||
|
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
|
||||||
|
assert_param(IS_GPIO_PIN(GPIO_Pin));
|
||||||
|
|
||||||
|
tmp |= GPIO_Pin;
|
||||||
|
/* Set LCKK bit */
|
||||||
|
GPIOx->LCKR = tmp;
|
||||||
|
/* Reset LCKK bit */
|
||||||
|
GPIOx->LCKR = GPIO_Pin;
|
||||||
|
/* Set LCKK bit */
|
||||||
|
GPIOx->LCKR = tmp;
|
||||||
|
/* Read LCKK bit*/
|
||||||
|
tmp = GPIOx->LCKR;
|
||||||
|
/* Read LCKK bit*/
|
||||||
|
tmp = GPIOx->LCKR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup GPIO_Group2 GPIO Read and Write
|
||||||
|
* @brief GPIO Read and Write
|
||||||
|
*
|
||||||
|
@verbatim
|
||||||
|
===============================================================================
|
||||||
|
##### GPIO Read and Write #####
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
@endverbatim
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads the specified input port pin.
|
||||||
|
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices
|
||||||
|
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices.
|
||||||
|
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices.
|
||||||
|
* @param GPIO_Pin: specifies the port bit to read.
|
||||||
|
* This parameter can be GPIO_Pin_x where x can be (0..15).
|
||||||
|
* @retval The input port pin value.
|
||||||
|
*/
|
||||||
|
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
|
||||||
|
{
|
||||||
|
uint8_t bitstatus = 0x00;
|
||||||
|
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
|
||||||
|
assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
|
||||||
|
|
||||||
|
if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET)
|
||||||
|
{
|
||||||
|
bitstatus = (uint8_t)Bit_SET;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bitstatus = (uint8_t)Bit_RESET;
|
||||||
|
}
|
||||||
|
return bitstatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads the specified GPIO input data port.
|
||||||
|
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices
|
||||||
|
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices.
|
||||||
|
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices.
|
||||||
|
* @retval GPIO input data port value.
|
||||||
|
*/
|
||||||
|
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
|
||||||
|
|
||||||
|
return ((uint16_t)GPIOx->IDR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads the specified output data port bit.
|
||||||
|
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices
|
||||||
|
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices.
|
||||||
|
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices.
|
||||||
|
* @param GPIO_Pin: specifies the port bit to read.
|
||||||
|
* This parameter can be GPIO_Pin_x where x can be (0..15).
|
||||||
|
* @retval The output port pin value.
|
||||||
|
*/
|
||||||
|
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
|
||||||
|
{
|
||||||
|
uint8_t bitstatus = 0x00;
|
||||||
|
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
|
||||||
|
assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
|
||||||
|
|
||||||
|
if (((GPIOx->ODR) & GPIO_Pin) != (uint32_t)Bit_RESET)
|
||||||
|
{
|
||||||
|
bitstatus = (uint8_t)Bit_SET;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bitstatus = (uint8_t)Bit_RESET;
|
||||||
|
}
|
||||||
|
return bitstatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads the specified GPIO output data port.
|
||||||
|
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices
|
||||||
|
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices.
|
||||||
|
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices.
|
||||||
|
* @retval GPIO output data port value.
|
||||||
|
*/
|
||||||
|
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
|
||||||
|
|
||||||
|
return ((uint16_t)GPIOx->ODR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the selected data port bits.
|
||||||
|
* @note This functions uses GPIOx_BSRR register to allow atomic read/modify
|
||||||
|
* accesses. In this way, there is no risk of an IRQ occurring between
|
||||||
|
* the read and the modify access.
|
||||||
|
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices
|
||||||
|
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices.
|
||||||
|
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices.
|
||||||
|
* @param GPIO_Pin: specifies the port bits to be written.
|
||||||
|
* This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
|
||||||
|
assert_param(IS_GPIO_PIN(GPIO_Pin));
|
||||||
|
|
||||||
|
GPIOx->BSRRL = GPIO_Pin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clears the selected data port bits.
|
||||||
|
* @note This functions uses GPIOx_BSRR register to allow atomic read/modify
|
||||||
|
* accesses. In this way, there is no risk of an IRQ occurring between
|
||||||
|
* the read and the modify access.
|
||||||
|
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices
|
||||||
|
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices.
|
||||||
|
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices.
|
||||||
|
* @param GPIO_Pin: specifies the port bits to be written.
|
||||||
|
* This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
|
||||||
|
assert_param(IS_GPIO_PIN(GPIO_Pin));
|
||||||
|
|
||||||
|
GPIOx->BSRRH = GPIO_Pin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets or clears the selected data port bit.
|
||||||
|
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices
|
||||||
|
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices.
|
||||||
|
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices.
|
||||||
|
* @param GPIO_Pin: specifies the port bit to be written.
|
||||||
|
* This parameter can be one of GPIO_Pin_x where x can be (0..15).
|
||||||
|
* @param BitVal: specifies the value to be written to the selected bit.
|
||||||
|
* This parameter can be one of the BitAction enum values:
|
||||||
|
* @arg Bit_RESET: to clear the port pin
|
||||||
|
* @arg Bit_SET: to set the port pin
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
|
||||||
|
assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
|
||||||
|
assert_param(IS_GPIO_BIT_ACTION(BitVal));
|
||||||
|
|
||||||
|
if (BitVal != Bit_RESET)
|
||||||
|
{
|
||||||
|
GPIOx->BSRRL = GPIO_Pin;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GPIOx->BSRRH = GPIO_Pin ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Writes data to the specified GPIO data port.
|
||||||
|
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices
|
||||||
|
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices.
|
||||||
|
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices.
|
||||||
|
* @param PortVal: specifies the value to be written to the port output data register.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
|
||||||
|
|
||||||
|
GPIOx->ODR = PortVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Toggles the specified GPIO pins..
|
||||||
|
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices
|
||||||
|
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices.
|
||||||
|
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices.
|
||||||
|
* @param GPIO_Pin: Specifies the pins to be toggled.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
|
||||||
|
|
||||||
|
GPIOx->ODR ^= GPIO_Pin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup GPIO_Group3 GPIO Alternate functions configuration function
|
||||||
|
* @brief GPIO Alternate functions configuration function
|
||||||
|
*
|
||||||
|
@verbatim
|
||||||
|
===============================================================================
|
||||||
|
##### GPIO Alternate functions configuration function #####
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
@endverbatim
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Changes the mapping of the specified pin.
|
||||||
|
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices
|
||||||
|
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices.
|
||||||
|
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices.
|
||||||
|
* @param GPIO_PinSource: specifies the pin for the Alternate function.
|
||||||
|
* This parameter can be GPIO_PinSourcex where x can be (0..15).
|
||||||
|
* @param GPIO_AFSelection: selects the pin to used as Alternate function.
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg GPIO_AF_RTC_50Hz: Connect RTC_50Hz pin to AF0 (default after reset)
|
||||||
|
* @arg GPIO_AF_MCO: Connect MCO pin (MCO1 and MCO2) to AF0 (default after reset)
|
||||||
|
* @arg GPIO_AF_TAMPER: Connect TAMPER pins (TAMPER_1 and TAMPER_2) to AF0 (default after reset)
|
||||||
|
* @arg GPIO_AF_SWJ: Connect SWJ pins (SWD and JTAG)to AF0 (default after reset)
|
||||||
|
* @arg GPIO_AF_TRACE: Connect TRACE pins to AF0 (default after reset)
|
||||||
|
* @arg GPIO_AF_TIM1: Connect TIM1 pins to AF1
|
||||||
|
* @arg GPIO_AF_TIM2: Connect TIM2 pins to AF1
|
||||||
|
* @arg GPIO_AF_TIM3: Connect TIM3 pins to AF2
|
||||||
|
* @arg GPIO_AF_TIM4: Connect TIM4 pins to AF2
|
||||||
|
* @arg GPIO_AF_TIM5: Connect TIM5 pins to AF2
|
||||||
|
* @arg GPIO_AF_TIM8: Connect TIM8 pins to AF3
|
||||||
|
* @arg GPIO_AF_TIM9: Connect TIM9 pins to AF3
|
||||||
|
* @arg GPIO_AF_TIM10: Connect TIM10 pins to AF3
|
||||||
|
* @arg GPIO_AF_TIM11: Connect TIM11 pins to AF3
|
||||||
|
* @arg GPIO_AF_I2C1: Connect I2C1 pins to AF4
|
||||||
|
* @arg GPIO_AF_I2C2: Connect I2C2 pins to AF4
|
||||||
|
* @arg GPIO_AF_I2C3: Connect I2C3 pins to AF4
|
||||||
|
* @arg GPIO_AF_SPI1: Connect SPI1 pins to AF5
|
||||||
|
* @arg GPIO_AF_SPI2: Connect SPI2/I2S2 pins to AF5
|
||||||
|
* @arg GPIO_AF_SPI4: Connect SPI4 pins to AF5
|
||||||
|
* @arg GPIO_AF_SPI5: Connect SPI5 pins to AF5
|
||||||
|
* @arg GPIO_AF_SPI6: Connect SPI6 pins to AF5
|
||||||
|
* @arg GPIO_AF_SAI1: Connect SAI1 pins to AF6 for STM32F42xxx/43xxx devices.
|
||||||
|
* @arg GPIO_AF_SPI3: Connect SPI3/I2S3 pins to AF6
|
||||||
|
* @arg GPIO_AF_I2S3ext: Connect I2S3ext pins to AF7
|
||||||
|
* @arg GPIO_AF_USART1: Connect USART1 pins to AF7
|
||||||
|
* @arg GPIO_AF_USART2: Connect USART2 pins to AF7
|
||||||
|
* @arg GPIO_AF_USART3: Connect USART3 pins to AF7
|
||||||
|
* @arg GPIO_AF_UART4: Connect UART4 pins to AF8
|
||||||
|
* @arg GPIO_AF_UART5: Connect UART5 pins to AF8
|
||||||
|
* @arg GPIO_AF_USART6: Connect USART6 pins to AF8
|
||||||
|
* @arg GPIO_AF_UART7: Connect UART7 pins to AF8
|
||||||
|
* @arg GPIO_AF_UART8: Connect UART8 pins to AF8
|
||||||
|
* @arg GPIO_AF_CAN1: Connect CAN1 pins to AF9
|
||||||
|
* @arg GPIO_AF_CAN2: Connect CAN2 pins to AF9
|
||||||
|
* @arg GPIO_AF_TIM12: Connect TIM12 pins to AF9
|
||||||
|
* @arg GPIO_AF_TIM13: Connect TIM13 pins to AF9
|
||||||
|
* @arg GPIO_AF_TIM14: Connect TIM14 pins to AF9
|
||||||
|
* @arg GPIO_AF_OTG_FS: Connect OTG_FS pins to AF10
|
||||||
|
* @arg GPIO_AF_OTG_HS: Connect OTG_HS pins to AF10
|
||||||
|
* @arg GPIO_AF_ETH: Connect ETHERNET pins to AF11
|
||||||
|
* @arg GPIO_AF_FSMC: Connect FSMC pins to AF12
|
||||||
|
* @arg GPIO_AF_FMC: Connect FMC pins to AF12 for STM32F42xxx/43xxx devices.
|
||||||
|
* @arg GPIO_AF_OTG_HS_FS: Connect OTG HS (configured in FS) pins to AF12
|
||||||
|
* @arg GPIO_AF_SDIO: Connect SDIO pins to AF12
|
||||||
|
* @arg GPIO_AF_DCMI: Connect DCMI pins to AF13
|
||||||
|
* @arg GPIO_AF_LTDC: Connect LTDC pins to AF14 for STM32F429xx/439xx devices.
|
||||||
|
* @arg GPIO_AF_EVENTOUT: Connect EVENTOUT pins to AF15
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)
|
||||||
|
{
|
||||||
|
uint32_t temp = 0x00;
|
||||||
|
uint32_t temp_2 = 0x00;
|
||||||
|
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
|
||||||
|
assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));
|
||||||
|
assert_param(IS_GPIO_AF(GPIO_AF));
|
||||||
|
|
||||||
|
temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ;
|
||||||
|
GPIOx->AFR[GPIO_PinSource >> 0x03] &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ;
|
||||||
|
temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] | temp;
|
||||||
|
GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -0,0 +1,136 @@
|
|||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||||
|
*
|
||||||
|
* $Date: 19. October 2015
|
||||||
|
* $Revision: V.1.4.5 a
|
||||||
|
*
|
||||||
|
* Project: CMSIS DSP Library
|
||||||
|
* Title: arm_common_tables.h
|
||||||
|
*
|
||||||
|
* Description: This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions
|
||||||
|
*
|
||||||
|
* Target Processor: Cortex-M4/Cortex-M3
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#ifndef _ARM_COMMON_TABLES_H
|
||||||
|
#define _ARM_COMMON_TABLES_H
|
||||||
|
|
||||||
|
#include "arm_math.h"
|
||||||
|
|
||||||
|
extern const uint16_t armBitRevTable[1024];
|
||||||
|
extern const q15_t armRecipTableQ15[64];
|
||||||
|
extern const q31_t armRecipTableQ31[64];
|
||||||
|
/* extern const q31_t realCoefAQ31[1024]; */
|
||||||
|
/* extern const q31_t realCoefBQ31[1024]; */
|
||||||
|
extern const float32_t twiddleCoef_16[32];
|
||||||
|
extern const float32_t twiddleCoef_32[64];
|
||||||
|
extern const float32_t twiddleCoef_64[128];
|
||||||
|
extern const float32_t twiddleCoef_128[256];
|
||||||
|
extern const float32_t twiddleCoef_256[512];
|
||||||
|
extern const float32_t twiddleCoef_512[1024];
|
||||||
|
extern const float32_t twiddleCoef_1024[2048];
|
||||||
|
extern const float32_t twiddleCoef_2048[4096];
|
||||||
|
extern const float32_t twiddleCoef_4096[8192];
|
||||||
|
#define twiddleCoef twiddleCoef_4096
|
||||||
|
extern const q31_t twiddleCoef_16_q31[24];
|
||||||
|
extern const q31_t twiddleCoef_32_q31[48];
|
||||||
|
extern const q31_t twiddleCoef_64_q31[96];
|
||||||
|
extern const q31_t twiddleCoef_128_q31[192];
|
||||||
|
extern const q31_t twiddleCoef_256_q31[384];
|
||||||
|
extern const q31_t twiddleCoef_512_q31[768];
|
||||||
|
extern const q31_t twiddleCoef_1024_q31[1536];
|
||||||
|
extern const q31_t twiddleCoef_2048_q31[3072];
|
||||||
|
extern const q31_t twiddleCoef_4096_q31[6144];
|
||||||
|
extern const q15_t twiddleCoef_16_q15[24];
|
||||||
|
extern const q15_t twiddleCoef_32_q15[48];
|
||||||
|
extern const q15_t twiddleCoef_64_q15[96];
|
||||||
|
extern const q15_t twiddleCoef_128_q15[192];
|
||||||
|
extern const q15_t twiddleCoef_256_q15[384];
|
||||||
|
extern const q15_t twiddleCoef_512_q15[768];
|
||||||
|
extern const q15_t twiddleCoef_1024_q15[1536];
|
||||||
|
extern const q15_t twiddleCoef_2048_q15[3072];
|
||||||
|
extern const q15_t twiddleCoef_4096_q15[6144];
|
||||||
|
extern const float32_t twiddleCoef_rfft_32[32];
|
||||||
|
extern const float32_t twiddleCoef_rfft_64[64];
|
||||||
|
extern const float32_t twiddleCoef_rfft_128[128];
|
||||||
|
extern const float32_t twiddleCoef_rfft_256[256];
|
||||||
|
extern const float32_t twiddleCoef_rfft_512[512];
|
||||||
|
extern const float32_t twiddleCoef_rfft_1024[1024];
|
||||||
|
extern const float32_t twiddleCoef_rfft_2048[2048];
|
||||||
|
extern const float32_t twiddleCoef_rfft_4096[4096];
|
||||||
|
|
||||||
|
|
||||||
|
/* floating-point bit reversal tables */
|
||||||
|
#define ARMBITREVINDEXTABLE__16_TABLE_LENGTH ((uint16_t)20 )
|
||||||
|
#define ARMBITREVINDEXTABLE__32_TABLE_LENGTH ((uint16_t)48 )
|
||||||
|
#define ARMBITREVINDEXTABLE__64_TABLE_LENGTH ((uint16_t)56 )
|
||||||
|
#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208 )
|
||||||
|
#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440 )
|
||||||
|
#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448 )
|
||||||
|
#define ARMBITREVINDEXTABLE1024_TABLE_LENGTH ((uint16_t)1800)
|
||||||
|
#define ARMBITREVINDEXTABLE2048_TABLE_LENGTH ((uint16_t)3808)
|
||||||
|
#define ARMBITREVINDEXTABLE4096_TABLE_LENGTH ((uint16_t)4032)
|
||||||
|
|
||||||
|
extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE__16_TABLE_LENGTH];
|
||||||
|
extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE__32_TABLE_LENGTH];
|
||||||
|
extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE__64_TABLE_LENGTH];
|
||||||
|
extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH];
|
||||||
|
extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH];
|
||||||
|
extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH];
|
||||||
|
extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE1024_TABLE_LENGTH];
|
||||||
|
extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE2048_TABLE_LENGTH];
|
||||||
|
extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE4096_TABLE_LENGTH];
|
||||||
|
|
||||||
|
/* fixed-point bit reversal tables */
|
||||||
|
#define ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH ((uint16_t)12 )
|
||||||
|
#define ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH ((uint16_t)24 )
|
||||||
|
#define ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH ((uint16_t)56 )
|
||||||
|
#define ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH ((uint16_t)112 )
|
||||||
|
#define ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH ((uint16_t)240 )
|
||||||
|
#define ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH ((uint16_t)480 )
|
||||||
|
#define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992 )
|
||||||
|
#define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984)
|
||||||
|
#define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032)
|
||||||
|
|
||||||
|
extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH];
|
||||||
|
extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH];
|
||||||
|
extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH];
|
||||||
|
extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH];
|
||||||
|
extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH];
|
||||||
|
extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH];
|
||||||
|
extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH];
|
||||||
|
extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH];
|
||||||
|
extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH];
|
||||||
|
|
||||||
|
/* Tables for Fast Math Sine and Cosine */
|
||||||
|
extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1];
|
||||||
|
extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1];
|
||||||
|
extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1];
|
||||||
|
|
||||||
|
#endif /* ARM_COMMON_TABLES_H */
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||||
|
*
|
||||||
|
* $Date: 19. March 2015
|
||||||
|
* $Revision: V.1.4.5
|
||||||
|
*
|
||||||
|
* Project: CMSIS DSP Library
|
||||||
|
* Title: arm_const_structs.h
|
||||||
|
*
|
||||||
|
* Description: This file has constant structs that are initialized for
|
||||||
|
* user convenience. For example, some can be given as
|
||||||
|
* arguments to the arm_cfft_f32() function.
|
||||||
|
*
|
||||||
|
* Target Processor: Cortex-M4/Cortex-M3
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#ifndef _ARM_CONST_STRUCTS_H
|
||||||
|
#define _ARM_CONST_STRUCTS_H
|
||||||
|
|
||||||
|
#include "arm_math.h"
|
||||||
|
#include "arm_common_tables.h"
|
||||||
|
|
||||||
|
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16;
|
||||||
|
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32;
|
||||||
|
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64;
|
||||||
|
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128;
|
||||||
|
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256;
|
||||||
|
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512;
|
||||||
|
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024;
|
||||||
|
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048;
|
||||||
|
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096;
|
||||||
|
|
||||||
|
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16;
|
||||||
|
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32;
|
||||||
|
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64;
|
||||||
|
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128;
|
||||||
|
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256;
|
||||||
|
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512;
|
||||||
|
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024;
|
||||||
|
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048;
|
||||||
|
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096;
|
||||||
|
|
||||||
|
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16;
|
||||||
|
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32;
|
||||||
|
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64;
|
||||||
|
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128;
|
||||||
|
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256;
|
||||||
|
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512;
|
||||||
|
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024;
|
||||||
|
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048;
|
||||||
|
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096;
|
||||||
|
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,734 @@
|
|||||||
|
/**************************************************************************//**
|
||||||
|
* @file cmsis_armcc.h
|
||||||
|
* @brief CMSIS Cortex-M Core Function/Instruction Header File
|
||||||
|
* @version V4.30
|
||||||
|
* @date 20. October 2015
|
||||||
|
******************************************************************************/
|
||||||
|
/* Copyright (c) 2009 - 2015 ARM LIMITED
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
to endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
*
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __CMSIS_ARMCC_H
|
||||||
|
#define __CMSIS_ARMCC_H
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
|
||||||
|
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ########################### Core Function Access ########################### */
|
||||||
|
/** \ingroup CMSIS_Core_FunctionInterface
|
||||||
|
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* intrinsic void __enable_irq(); */
|
||||||
|
/* intrinsic void __disable_irq(); */
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Control Register
|
||||||
|
\details Returns the content of the Control Register.
|
||||||
|
\return Control Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_CONTROL(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regControl __ASM("control");
|
||||||
|
return(__regControl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Control Register
|
||||||
|
\details Writes the given value to the Control Register.
|
||||||
|
\param [in] control Control Register value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_CONTROL(uint32_t control)
|
||||||
|
{
|
||||||
|
register uint32_t __regControl __ASM("control");
|
||||||
|
__regControl = control;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get IPSR Register
|
||||||
|
\details Returns the content of the IPSR Register.
|
||||||
|
\return IPSR Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_IPSR(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regIPSR __ASM("ipsr");
|
||||||
|
return(__regIPSR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get APSR Register
|
||||||
|
\details Returns the content of the APSR Register.
|
||||||
|
\return APSR Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_APSR(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regAPSR __ASM("apsr");
|
||||||
|
return(__regAPSR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get xPSR Register
|
||||||
|
\details Returns the content of the xPSR Register.
|
||||||
|
\return xPSR Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_xPSR(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regXPSR __ASM("xpsr");
|
||||||
|
return(__regXPSR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Process Stack Pointer
|
||||||
|
\details Returns the current value of the Process Stack Pointer (PSP).
|
||||||
|
\return PSP Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_PSP(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||||
|
return(__regProcessStackPointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Process Stack Pointer
|
||||||
|
\details Assigns the given value to the Process Stack Pointer (PSP).
|
||||||
|
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
|
||||||
|
{
|
||||||
|
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||||
|
__regProcessStackPointer = topOfProcStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Main Stack Pointer
|
||||||
|
\details Returns the current value of the Main Stack Pointer (MSP).
|
||||||
|
\return MSP Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_MSP(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regMainStackPointer __ASM("msp");
|
||||||
|
return(__regMainStackPointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Main Stack Pointer
|
||||||
|
\details Assigns the given value to the Main Stack Pointer (MSP).
|
||||||
|
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
|
||||||
|
{
|
||||||
|
register uint32_t __regMainStackPointer __ASM("msp");
|
||||||
|
__regMainStackPointer = topOfMainStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Priority Mask
|
||||||
|
\details Returns the current state of the priority mask bit from the Priority Mask Register.
|
||||||
|
\return Priority Mask value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_PRIMASK(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regPriMask __ASM("primask");
|
||||||
|
return(__regPriMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Priority Mask
|
||||||
|
\details Assigns the given value to the Priority Mask Register.
|
||||||
|
\param [in] priMask Priority Mask
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
|
||||||
|
{
|
||||||
|
register uint32_t __regPriMask __ASM("primask");
|
||||||
|
__regPriMask = (priMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Enable FIQ
|
||||||
|
\details Enables FIQ interrupts by clearing the F-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
#define __enable_fault_irq __enable_fiq
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Disable FIQ
|
||||||
|
\details Disables FIQ interrupts by setting the F-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
#define __disable_fault_irq __disable_fiq
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Base Priority
|
||||||
|
\details Returns the current value of the Base Priority register.
|
||||||
|
\return Base Priority register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_BASEPRI(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regBasePri __ASM("basepri");
|
||||||
|
return(__regBasePri);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Base Priority
|
||||||
|
\details Assigns the given value to the Base Priority register.
|
||||||
|
\param [in] basePri Base Priority value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
|
||||||
|
{
|
||||||
|
register uint32_t __regBasePri __ASM("basepri");
|
||||||
|
__regBasePri = (basePri & 0xFFU);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Base Priority with condition
|
||||||
|
\details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
|
||||||
|
or the new value increases the BASEPRI priority level.
|
||||||
|
\param [in] basePri Base Priority value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
|
||||||
|
{
|
||||||
|
register uint32_t __regBasePriMax __ASM("basepri_max");
|
||||||
|
__regBasePriMax = (basePri & 0xFFU);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Fault Mask
|
||||||
|
\details Returns the current value of the Fault Mask register.
|
||||||
|
\return Fault Mask register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regFaultMask __ASM("faultmask");
|
||||||
|
return(__regFaultMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Fault Mask
|
||||||
|
\details Assigns the given value to the Fault Mask register.
|
||||||
|
\param [in] faultMask Fault Mask value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
|
||||||
|
{
|
||||||
|
register uint32_t __regFaultMask __ASM("faultmask");
|
||||||
|
__regFaultMask = (faultMask & (uint32_t)1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
|
||||||
|
|
||||||
|
|
||||||
|
#if (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get FPSCR
|
||||||
|
\details Returns the current value of the Floating Point Status/Control register.
|
||||||
|
\return Floating Point Status/Control register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_FPSCR(void)
|
||||||
|
{
|
||||||
|
#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
|
||||||
|
register uint32_t __regfpscr __ASM("fpscr");
|
||||||
|
return(__regfpscr);
|
||||||
|
#else
|
||||||
|
return(0U);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set FPSCR
|
||||||
|
\details Assigns the given value to the Floating Point Status/Control register.
|
||||||
|
\param [in] fpscr Floating Point Status/Control value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
||||||
|
{
|
||||||
|
#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
|
||||||
|
register uint32_t __regfpscr __ASM("fpscr");
|
||||||
|
__regfpscr = (fpscr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*@} end of CMSIS_Core_RegAccFunctions */
|
||||||
|
|
||||||
|
|
||||||
|
/* ########################## Core Instruction Access ######################### */
|
||||||
|
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
|
||||||
|
Access to dedicated instructions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief No Operation
|
||||||
|
\details No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||||
|
*/
|
||||||
|
#define __NOP __nop
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Wait For Interrupt
|
||||||
|
\details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
|
||||||
|
*/
|
||||||
|
#define __WFI __wfi
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Wait For Event
|
||||||
|
\details Wait For Event is a hint instruction that permits the processor to enter
|
||||||
|
a low-power state until one of a number of events occurs.
|
||||||
|
*/
|
||||||
|
#define __WFE __wfe
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Send Event
|
||||||
|
\details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||||
|
*/
|
||||||
|
#define __SEV __sev
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Instruction Synchronization Barrier
|
||||||
|
\details Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||||
|
so that all instructions following the ISB are fetched from cache or memory,
|
||||||
|
after the instruction has been completed.
|
||||||
|
*/
|
||||||
|
#define __ISB() do {\
|
||||||
|
__schedule_barrier();\
|
||||||
|
__isb(0xF);\
|
||||||
|
__schedule_barrier();\
|
||||||
|
} while (0U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Data Synchronization Barrier
|
||||||
|
\details Acts as a special kind of Data Memory Barrier.
|
||||||
|
It completes when all explicit memory accesses before this instruction complete.
|
||||||
|
*/
|
||||||
|
#define __DSB() do {\
|
||||||
|
__schedule_barrier();\
|
||||||
|
__dsb(0xF);\
|
||||||
|
__schedule_barrier();\
|
||||||
|
} while (0U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Data Memory Barrier
|
||||||
|
\details Ensures the apparent order of the explicit memory operations before
|
||||||
|
and after the instruction, without ensuring their completion.
|
||||||
|
*/
|
||||||
|
#define __DMB() do {\
|
||||||
|
__schedule_barrier();\
|
||||||
|
__dmb(0xF);\
|
||||||
|
__schedule_barrier();\
|
||||||
|
} while (0U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Reverse byte order (32 bit)
|
||||||
|
\details Reverses the byte order in integer value.
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
#define __REV __rev
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Reverse byte order (16 bit)
|
||||||
|
\details Reverses the byte order in two unsigned short values.
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
#ifndef __NO_EMBEDDED_ASM
|
||||||
|
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
|
||||||
|
{
|
||||||
|
rev16 r0, r0
|
||||||
|
bx lr
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Reverse byte order in signed short value
|
||||||
|
\details Reverses the byte order in a signed short value with sign extension to integer.
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
#ifndef __NO_EMBEDDED_ASM
|
||||||
|
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
|
||||||
|
{
|
||||||
|
revsh r0, r0
|
||||||
|
bx lr
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Rotate Right in unsigned value (32 bit)
|
||||||
|
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||||
|
\param [in] value Value to rotate
|
||||||
|
\param [in] value Number of Bits to rotate
|
||||||
|
\return Rotated value
|
||||||
|
*/
|
||||||
|
#define __ROR __ror
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Breakpoint
|
||||||
|
\details Causes the processor to enter Debug state.
|
||||||
|
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
|
||||||
|
\param [in] value is ignored by the processor.
|
||||||
|
If required, a debugger can use it to store additional information about the breakpoint.
|
||||||
|
*/
|
||||||
|
#define __BKPT(value) __breakpoint(value)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Reverse bit order of value
|
||||||
|
\details Reverses the bit order of the given value.
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
|
||||||
|
#define __RBIT __rbit
|
||||||
|
#else
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
|
||||||
|
|
||||||
|
result = value; /* r will be reversed bits of v; first get LSB of v */
|
||||||
|
for (value >>= 1U; value; value >>= 1U)
|
||||||
|
{
|
||||||
|
result <<= 1U;
|
||||||
|
result |= value & 1U;
|
||||||
|
s--;
|
||||||
|
}
|
||||||
|
result <<= s; /* shift when v's highest bits are zero */
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Count leading zeros
|
||||||
|
\details Counts the number of leading zeros of a data value.
|
||||||
|
\param [in] value Value to count the leading zeros
|
||||||
|
\return number of leading zeros in value
|
||||||
|
*/
|
||||||
|
#define __CLZ __clz
|
||||||
|
|
||||||
|
|
||||||
|
#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief LDR Exclusive (8 bit)
|
||||||
|
\details Executes a exclusive LDR instruction for 8 bit value.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint8_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||||
|
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
|
||||||
|
#else
|
||||||
|
#define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief LDR Exclusive (16 bit)
|
||||||
|
\details Executes a exclusive LDR instruction for 16 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint16_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||||
|
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
|
||||||
|
#else
|
||||||
|
#define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief LDR Exclusive (32 bit)
|
||||||
|
\details Executes a exclusive LDR instruction for 32 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint32_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||||
|
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
|
||||||
|
#else
|
||||||
|
#define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STR Exclusive (8 bit)
|
||||||
|
\details Executes a exclusive STR instruction for 8 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||||
|
#define __STREXB(value, ptr) __strex(value, ptr)
|
||||||
|
#else
|
||||||
|
#define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STR Exclusive (16 bit)
|
||||||
|
\details Executes a exclusive STR instruction for 16 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||||
|
#define __STREXH(value, ptr) __strex(value, ptr)
|
||||||
|
#else
|
||||||
|
#define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STR Exclusive (32 bit)
|
||||||
|
\details Executes a exclusive STR instruction for 32 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||||
|
#define __STREXW(value, ptr) __strex(value, ptr)
|
||||||
|
#else
|
||||||
|
#define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Remove the exclusive lock
|
||||||
|
\details Removes the exclusive lock which is created by LDREX.
|
||||||
|
*/
|
||||||
|
#define __CLREX __clrex
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Signed Saturate
|
||||||
|
\details Saturates a signed value.
|
||||||
|
\param [in] value Value to be saturated
|
||||||
|
\param [in] sat Bit position to saturate to (1..32)
|
||||||
|
\return Saturated value
|
||||||
|
*/
|
||||||
|
#define __SSAT __ssat
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Unsigned Saturate
|
||||||
|
\details Saturates an unsigned value.
|
||||||
|
\param [in] value Value to be saturated
|
||||||
|
\param [in] sat Bit position to saturate to (0..31)
|
||||||
|
\return Saturated value
|
||||||
|
*/
|
||||||
|
#define __USAT __usat
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Rotate Right with Extend (32 bit)
|
||||||
|
\details Moves each bit of a bitstring right by one bit.
|
||||||
|
The carry input is shifted in at the left end of the bitstring.
|
||||||
|
\param [in] value Value to rotate
|
||||||
|
\return Rotated value
|
||||||
|
*/
|
||||||
|
#ifndef __NO_EMBEDDED_ASM
|
||||||
|
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
|
||||||
|
{
|
||||||
|
rrx r0, r0
|
||||||
|
bx lr
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief LDRT Unprivileged (8 bit)
|
||||||
|
\details Executes a Unprivileged LDRT instruction for 8 bit value.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint8_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief LDRT Unprivileged (16 bit)
|
||||||
|
\details Executes a Unprivileged LDRT instruction for 16 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint16_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief LDRT Unprivileged (32 bit)
|
||||||
|
\details Executes a Unprivileged LDRT instruction for 32 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint32_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STRT Unprivileged (8 bit)
|
||||||
|
\details Executes a Unprivileged STRT instruction for 8 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
#define __STRBT(value, ptr) __strt(value, ptr)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STRT Unprivileged (16 bit)
|
||||||
|
\details Executes a Unprivileged STRT instruction for 16 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
#define __STRHT(value, ptr) __strt(value, ptr)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STRT Unprivileged (32 bit)
|
||||||
|
\details Executes a Unprivileged STRT instruction for 32 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
#define __STRT(value, ptr) __strt(value, ptr)
|
||||||
|
|
||||||
|
#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
|
||||||
|
|
||||||
|
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
|
||||||
|
|
||||||
|
|
||||||
|
/* ################### Compiler specific Intrinsics ########################### */
|
||||||
|
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
|
||||||
|
Access to dedicated SIMD instructions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if (__CORTEX_M >= 0x04U) /* only for Cortex-M4 and above */
|
||||||
|
|
||||||
|
#define __SADD8 __sadd8
|
||||||
|
#define __QADD8 __qadd8
|
||||||
|
#define __SHADD8 __shadd8
|
||||||
|
#define __UADD8 __uadd8
|
||||||
|
#define __UQADD8 __uqadd8
|
||||||
|
#define __UHADD8 __uhadd8
|
||||||
|
#define __SSUB8 __ssub8
|
||||||
|
#define __QSUB8 __qsub8
|
||||||
|
#define __SHSUB8 __shsub8
|
||||||
|
#define __USUB8 __usub8
|
||||||
|
#define __UQSUB8 __uqsub8
|
||||||
|
#define __UHSUB8 __uhsub8
|
||||||
|
#define __SADD16 __sadd16
|
||||||
|
#define __QADD16 __qadd16
|
||||||
|
#define __SHADD16 __shadd16
|
||||||
|
#define __UADD16 __uadd16
|
||||||
|
#define __UQADD16 __uqadd16
|
||||||
|
#define __UHADD16 __uhadd16
|
||||||
|
#define __SSUB16 __ssub16
|
||||||
|
#define __QSUB16 __qsub16
|
||||||
|
#define __SHSUB16 __shsub16
|
||||||
|
#define __USUB16 __usub16
|
||||||
|
#define __UQSUB16 __uqsub16
|
||||||
|
#define __UHSUB16 __uhsub16
|
||||||
|
#define __SASX __sasx
|
||||||
|
#define __QASX __qasx
|
||||||
|
#define __SHASX __shasx
|
||||||
|
#define __UASX __uasx
|
||||||
|
#define __UQASX __uqasx
|
||||||
|
#define __UHASX __uhasx
|
||||||
|
#define __SSAX __ssax
|
||||||
|
#define __QSAX __qsax
|
||||||
|
#define __SHSAX __shsax
|
||||||
|
#define __USAX __usax
|
||||||
|
#define __UQSAX __uqsax
|
||||||
|
#define __UHSAX __uhsax
|
||||||
|
#define __USAD8 __usad8
|
||||||
|
#define __USADA8 __usada8
|
||||||
|
#define __SSAT16 __ssat16
|
||||||
|
#define __USAT16 __usat16
|
||||||
|
#define __UXTB16 __uxtb16
|
||||||
|
#define __UXTAB16 __uxtab16
|
||||||
|
#define __SXTB16 __sxtb16
|
||||||
|
#define __SXTAB16 __sxtab16
|
||||||
|
#define __SMUAD __smuad
|
||||||
|
#define __SMUADX __smuadx
|
||||||
|
#define __SMLAD __smlad
|
||||||
|
#define __SMLADX __smladx
|
||||||
|
#define __SMLALD __smlald
|
||||||
|
#define __SMLALDX __smlaldx
|
||||||
|
#define __SMUSD __smusd
|
||||||
|
#define __SMUSDX __smusdx
|
||||||
|
#define __SMLSD __smlsd
|
||||||
|
#define __SMLSDX __smlsdx
|
||||||
|
#define __SMLSLD __smlsld
|
||||||
|
#define __SMLSLDX __smlsldx
|
||||||
|
#define __SEL __sel
|
||||||
|
#define __QADD __qadd
|
||||||
|
#define __QSUB __qsub
|
||||||
|
|
||||||
|
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
|
||||||
|
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
|
||||||
|
|
||||||
|
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
|
||||||
|
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
|
||||||
|
|
||||||
|
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
|
||||||
|
((int64_t)(ARG3) << 32U) ) >> 32U))
|
||||||
|
|
||||||
|
#endif /* (__CORTEX_M >= 0x04) */
|
||||||
|
/*@} end of group CMSIS_SIMD_intrinsics */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __CMSIS_ARMCC_H */
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,798 @@
|
|||||||
|
/**************************************************************************//**
|
||||||
|
* @file core_cm0.h
|
||||||
|
* @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File
|
||||||
|
* @version V4.30
|
||||||
|
* @date 20. October 2015
|
||||||
|
******************************************************************************/
|
||||||
|
/* Copyright (c) 2009 - 2015 ARM LIMITED
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
to endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
*
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#if defined ( __ICCARM__ )
|
||||||
|
#pragma system_include /* treat file as system include file for MISRA check */
|
||||||
|
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||||
|
#pragma clang system_header /* treat file as system include file */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __CORE_CM0_H_GENERIC
|
||||||
|
#define __CORE_CM0_H_GENERIC
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
\page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
|
||||||
|
CMSIS violates the following MISRA-C:2004 rules:
|
||||||
|
|
||||||
|
\li Required Rule 8.5, object/function definition in header file.<br>
|
||||||
|
Function definitions in header files are used to allow 'inlining'.
|
||||||
|
|
||||||
|
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
|
||||||
|
Unions are used for effective representation of core registers.
|
||||||
|
|
||||||
|
\li Advisory Rule 19.7, Function-like macro defined.<br>
|
||||||
|
Function-like macros are used to allow more efficient code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* CMSIS definitions
|
||||||
|
******************************************************************************/
|
||||||
|
/**
|
||||||
|
\ingroup Cortex_M0
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* CMSIS CM0 definitions */
|
||||||
|
#define __CM0_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
|
||||||
|
#define __CM0_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
|
||||||
|
#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \
|
||||||
|
__CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
|
||||||
|
|
||||||
|
#define __CORTEX_M (0x00U) /*!< Cortex-M Core */
|
||||||
|
|
||||||
|
|
||||||
|
#if defined ( __CC_ARM )
|
||||||
|
#define __ASM __asm /*!< asm keyword for ARM Compiler */
|
||||||
|
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
|
||||||
|
#define __STATIC_INLINE static __inline
|
||||||
|
|
||||||
|
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||||
|
#define __ASM __asm /*!< asm keyword for ARM Compiler */
|
||||||
|
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
|
||||||
|
#define __STATIC_INLINE static __inline
|
||||||
|
|
||||||
|
#elif defined ( __GNUC__ )
|
||||||
|
#define __ASM __asm /*!< asm keyword for GNU Compiler */
|
||||||
|
#define __INLINE inline /*!< inline keyword for GNU Compiler */
|
||||||
|
#define __STATIC_INLINE static inline
|
||||||
|
|
||||||
|
#elif defined ( __ICCARM__ )
|
||||||
|
#define __ASM __asm /*!< asm keyword for IAR Compiler */
|
||||||
|
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
|
||||||
|
#define __STATIC_INLINE static inline
|
||||||
|
|
||||||
|
#elif defined ( __TMS470__ )
|
||||||
|
#define __ASM __asm /*!< asm keyword for TI CCS Compiler */
|
||||||
|
#define __STATIC_INLINE static inline
|
||||||
|
|
||||||
|
#elif defined ( __TASKING__ )
|
||||||
|
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
|
||||||
|
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
|
||||||
|
#define __STATIC_INLINE static inline
|
||||||
|
|
||||||
|
#elif defined ( __CSMC__ )
|
||||||
|
#define __packed
|
||||||
|
#define __ASM _asm /*!< asm keyword for COSMIC Compiler */
|
||||||
|
#define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
|
||||||
|
#define __STATIC_INLINE static inline
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error Unknown compiler
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** __FPU_USED indicates whether an FPU is used or not.
|
||||||
|
This core does not support an FPU at all
|
||||||
|
*/
|
||||||
|
#define __FPU_USED 0U
|
||||||
|
|
||||||
|
#if defined ( __CC_ARM )
|
||||||
|
#if defined __TARGET_FPU_VFP
|
||||||
|
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||||
|
#if defined __ARM_PCS_VFP
|
||||||
|
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined ( __GNUC__ )
|
||||||
|
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||||
|
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined ( __ICCARM__ )
|
||||||
|
#if defined __ARMVFP__
|
||||||
|
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined ( __TMS470__ )
|
||||||
|
#if defined __TI_VFP_SUPPORT__
|
||||||
|
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined ( __TASKING__ )
|
||||||
|
#if defined __FPU_VFP__
|
||||||
|
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined ( __CSMC__ )
|
||||||
|
#if ( __CSMC__ & 0x400U)
|
||||||
|
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "core_cmInstr.h" /* Core Instruction Access */
|
||||||
|
#include "core_cmFunc.h" /* Core Function Access */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __CORE_CM0_H_GENERIC */
|
||||||
|
|
||||||
|
#ifndef __CMSIS_GENERIC
|
||||||
|
|
||||||
|
#ifndef __CORE_CM0_H_DEPENDANT
|
||||||
|
#define __CORE_CM0_H_DEPENDANT
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* check device defines and use defaults */
|
||||||
|
#if defined __CHECK_DEVICE_DEFINES
|
||||||
|
#ifndef __CM0_REV
|
||||||
|
#define __CM0_REV 0x0000U
|
||||||
|
#warning "__CM0_REV not defined in device header file; using default!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __NVIC_PRIO_BITS
|
||||||
|
#define __NVIC_PRIO_BITS 2U
|
||||||
|
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __Vendor_SysTickConfig
|
||||||
|
#define __Vendor_SysTickConfig 0U
|
||||||
|
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* IO definitions (access restrictions to peripheral registers) */
|
||||||
|
/**
|
||||||
|
\defgroup CMSIS_glob_defs CMSIS Global Defines
|
||||||
|
|
||||||
|
<strong>IO Type Qualifiers</strong> are used
|
||||||
|
\li to specify the access to peripheral variables.
|
||||||
|
\li for automatic generation of peripheral register debug information.
|
||||||
|
*/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define __I volatile /*!< Defines 'read only' permissions */
|
||||||
|
#else
|
||||||
|
#define __I volatile const /*!< Defines 'read only' permissions */
|
||||||
|
#endif
|
||||||
|
#define __O volatile /*!< Defines 'write only' permissions */
|
||||||
|
#define __IO volatile /*!< Defines 'read / write' permissions */
|
||||||
|
|
||||||
|
/* following defines should be used for structure members */
|
||||||
|
#define __IM volatile const /*! Defines 'read only' structure member permissions */
|
||||||
|
#define __OM volatile /*! Defines 'write only' structure member permissions */
|
||||||
|
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
|
||||||
|
|
||||||
|
/*@} end of group Cortex_M0 */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Register Abstraction
|
||||||
|
Core Register contain:
|
||||||
|
- Core Register
|
||||||
|
- Core NVIC Register
|
||||||
|
- Core SCB Register
|
||||||
|
- Core SysTick Register
|
||||||
|
******************************************************************************/
|
||||||
|
/**
|
||||||
|
\defgroup CMSIS_core_register Defines and Type Definitions
|
||||||
|
\brief Type definitions and defines for Cortex-M processor based devices.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_CORE Status and Control Registers
|
||||||
|
\brief Core Register type definitions.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Union type to access the Application Program Status Register (APSR).
|
||||||
|
*/
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
|
||||||
|
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||||
|
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||||
|
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||||
|
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||||
|
} b; /*!< Structure used for bit access */
|
||||||
|
uint32_t w; /*!< Type used for word access */
|
||||||
|
} APSR_Type;
|
||||||
|
|
||||||
|
/* APSR Register Definitions */
|
||||||
|
#define APSR_N_Pos 31U /*!< APSR: N Position */
|
||||||
|
#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
|
||||||
|
|
||||||
|
#define APSR_Z_Pos 30U /*!< APSR: Z Position */
|
||||||
|
#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
|
||||||
|
|
||||||
|
#define APSR_C_Pos 29U /*!< APSR: C Position */
|
||||||
|
#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
|
||||||
|
|
||||||
|
#define APSR_V_Pos 28U /*!< APSR: V Position */
|
||||||
|
#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Union type to access the Interrupt Program Status Register (IPSR).
|
||||||
|
*/
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
|
||||||
|
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
|
||||||
|
} b; /*!< Structure used for bit access */
|
||||||
|
uint32_t w; /*!< Type used for word access */
|
||||||
|
} IPSR_Type;
|
||||||
|
|
||||||
|
/* IPSR Register Definitions */
|
||||||
|
#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
|
||||||
|
#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Union type to access the Special-Purpose Program Status Registers (xPSR).
|
||||||
|
*/
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
|
||||||
|
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
|
||||||
|
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
|
||||||
|
uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
|
||||||
|
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||||
|
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||||
|
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||||
|
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||||
|
} b; /*!< Structure used for bit access */
|
||||||
|
uint32_t w; /*!< Type used for word access */
|
||||||
|
} xPSR_Type;
|
||||||
|
|
||||||
|
/* xPSR Register Definitions */
|
||||||
|
#define xPSR_N_Pos 31U /*!< xPSR: N Position */
|
||||||
|
#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
|
||||||
|
|
||||||
|
#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
|
||||||
|
#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
|
||||||
|
|
||||||
|
#define xPSR_C_Pos 29U /*!< xPSR: C Position */
|
||||||
|
#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
|
||||||
|
|
||||||
|
#define xPSR_V_Pos 28U /*!< xPSR: V Position */
|
||||||
|
#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
|
||||||
|
|
||||||
|
#define xPSR_T_Pos 24U /*!< xPSR: T Position */
|
||||||
|
#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
|
||||||
|
|
||||||
|
#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
|
||||||
|
#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Union type to access the Control Registers (CONTROL).
|
||||||
|
*/
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t _reserved0:1; /*!< bit: 0 Reserved */
|
||||||
|
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
|
||||||
|
uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
|
||||||
|
} b; /*!< Structure used for bit access */
|
||||||
|
uint32_t w; /*!< Type used for word access */
|
||||||
|
} CONTROL_Type;
|
||||||
|
|
||||||
|
/* CONTROL Register Definitions */
|
||||||
|
#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
|
||||||
|
#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_CORE */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
|
||||||
|
\brief Type definitions for the NVIC Registers
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
|
||||||
|
uint32_t RESERVED0[31U];
|
||||||
|
__IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
|
||||||
|
uint32_t RSERVED1[31U];
|
||||||
|
__IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
|
||||||
|
uint32_t RESERVED2[31U];
|
||||||
|
__IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
|
||||||
|
uint32_t RESERVED3[31U];
|
||||||
|
uint32_t RESERVED4[64U];
|
||||||
|
__IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
|
||||||
|
} NVIC_Type;
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_NVIC */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_SCB System Control Block (SCB)
|
||||||
|
\brief Type definitions for the System Control Block Registers
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Structure type to access the System Control Block (SCB).
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
|
||||||
|
__IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
|
||||||
|
uint32_t RESERVED0;
|
||||||
|
__IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
|
||||||
|
__IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
|
||||||
|
__IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
|
||||||
|
uint32_t RESERVED1;
|
||||||
|
__IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
|
||||||
|
__IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
|
||||||
|
} SCB_Type;
|
||||||
|
|
||||||
|
/* SCB CPUID Register Definitions */
|
||||||
|
#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
|
||||||
|
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
|
||||||
|
|
||||||
|
#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
|
||||||
|
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
|
||||||
|
|
||||||
|
#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
|
||||||
|
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
|
||||||
|
|
||||||
|
#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
|
||||||
|
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
|
||||||
|
|
||||||
|
#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
|
||||||
|
#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
|
||||||
|
|
||||||
|
/* SCB Interrupt Control State Register Definitions */
|
||||||
|
#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
|
||||||
|
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
|
||||||
|
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
|
||||||
|
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
|
||||||
|
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
|
||||||
|
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
|
||||||
|
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
|
||||||
|
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
|
||||||
|
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
|
||||||
|
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
|
||||||
|
|
||||||
|
/* SCB Application Interrupt and Reset Control Register Definitions */
|
||||||
|
#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
|
||||||
|
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
|
||||||
|
|
||||||
|
#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
|
||||||
|
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
|
||||||
|
|
||||||
|
#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
|
||||||
|
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
|
||||||
|
|
||||||
|
#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
|
||||||
|
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
|
||||||
|
|
||||||
|
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
|
||||||
|
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
|
||||||
|
|
||||||
|
/* SCB System Control Register Definitions */
|
||||||
|
#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
|
||||||
|
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
|
||||||
|
|
||||||
|
#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
|
||||||
|
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
|
||||||
|
|
||||||
|
#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
|
||||||
|
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
|
||||||
|
|
||||||
|
/* SCB Configuration Control Register Definitions */
|
||||||
|
#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
|
||||||
|
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
|
||||||
|
|
||||||
|
#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
|
||||||
|
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
|
||||||
|
|
||||||
|
/* SCB System Handler Control and State Register Definitions */
|
||||||
|
#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
|
||||||
|
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_SCB */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
|
||||||
|
\brief Type definitions for the System Timer Registers.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Structure type to access the System Timer (SysTick).
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
|
||||||
|
__IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
|
||||||
|
__IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
|
||||||
|
__IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
|
||||||
|
} SysTick_Type;
|
||||||
|
|
||||||
|
/* SysTick Control / Status Register Definitions */
|
||||||
|
#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
|
||||||
|
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
|
||||||
|
|
||||||
|
#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
|
||||||
|
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
|
||||||
|
|
||||||
|
#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
|
||||||
|
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
|
||||||
|
|
||||||
|
#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
|
||||||
|
#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
|
||||||
|
|
||||||
|
/* SysTick Reload Register Definitions */
|
||||||
|
#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
|
||||||
|
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
|
||||||
|
|
||||||
|
/* SysTick Current Register Definitions */
|
||||||
|
#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
|
||||||
|
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
|
||||||
|
|
||||||
|
/* SysTick Calibration Register Definitions */
|
||||||
|
#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
|
||||||
|
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
|
||||||
|
|
||||||
|
#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
|
||||||
|
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
|
||||||
|
|
||||||
|
#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
|
||||||
|
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_SysTick */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
|
||||||
|
\brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
|
||||||
|
Therefore they are not covered by the Cortex-M0 header file.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
/*@} end of group CMSIS_CoreDebug */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_core_bitfield Core register bit field macros
|
||||||
|
\brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Mask and shift a bit field value for use in a register bit range.
|
||||||
|
\param[in] field Name of the register bit field.
|
||||||
|
\param[in] value Value of the bit field.
|
||||||
|
\return Masked and shifted value.
|
||||||
|
*/
|
||||||
|
#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Mask and shift a register value to extract a bit filed value.
|
||||||
|
\param[in] field Name of the register bit field.
|
||||||
|
\param[in] value Value of register.
|
||||||
|
\return Masked and shifted bit field value.
|
||||||
|
*/
|
||||||
|
#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_core_bitfield */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_core_base Core Definitions
|
||||||
|
\brief Definitions for base addresses, unions, and structures.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Memory mapping of Cortex-M0 Hardware */
|
||||||
|
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
|
||||||
|
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
|
||||||
|
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
|
||||||
|
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
|
||||||
|
|
||||||
|
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
|
||||||
|
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
|
||||||
|
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
|
||||||
|
|
||||||
|
|
||||||
|
/*@} */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Hardware Abstraction Layer
|
||||||
|
Core Function Interface contains:
|
||||||
|
- Core NVIC Functions
|
||||||
|
- Core SysTick Functions
|
||||||
|
- Core Register Access Functions
|
||||||
|
******************************************************************************/
|
||||||
|
/**
|
||||||
|
\defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ########################## NVIC functions #################################### */
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_Core_FunctionInterface
|
||||||
|
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
|
||||||
|
\brief Functions that manage interrupts and exceptions via the NVIC.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Interrupt Priorities are WORD accessible only under ARMv6M */
|
||||||
|
/* The following MACROS handle generation of the register offset and byte masks */
|
||||||
|
#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
|
||||||
|
#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
|
||||||
|
#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Enable External Interrupt
|
||||||
|
\details Enables a device-specific interrupt in the NVIC interrupt controller.
|
||||||
|
\param [in] IRQn External interrupt number. Value cannot be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Disable External Interrupt
|
||||||
|
\details Disables a device-specific interrupt in the NVIC interrupt controller.
|
||||||
|
\param [in] IRQn External interrupt number. Value cannot be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Pending Interrupt
|
||||||
|
\details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
|
||||||
|
\param [in] IRQn Interrupt number.
|
||||||
|
\return 0 Interrupt status is not pending.
|
||||||
|
\return 1 Interrupt status is pending.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Pending Interrupt
|
||||||
|
\details Sets the pending bit of an external interrupt.
|
||||||
|
\param [in] IRQn Interrupt number. Value cannot be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Clear Pending Interrupt
|
||||||
|
\details Clears the pending bit of an external interrupt.
|
||||||
|
\param [in] IRQn External interrupt number. Value cannot be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Interrupt Priority
|
||||||
|
\details Sets the priority of an interrupt.
|
||||||
|
\note The priority cannot be set for every core interrupt.
|
||||||
|
\param [in] IRQn Interrupt number.
|
||||||
|
\param [in] priority Priority to set.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
|
||||||
|
{
|
||||||
|
if ((int32_t)(IRQn) < 0)
|
||||||
|
{
|
||||||
|
SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||||
|
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||||
|
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Interrupt Priority
|
||||||
|
\details Reads the priority of an interrupt.
|
||||||
|
The interrupt number can be positive to specify an external (device specific) interrupt,
|
||||||
|
or negative to specify an internal (core) interrupt.
|
||||||
|
\param [in] IRQn Interrupt number.
|
||||||
|
\return Interrupt Priority.
|
||||||
|
Value is aligned automatically to the implemented priority bits of the microcontroller.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ((int32_t)(IRQn) < 0)
|
||||||
|
{
|
||||||
|
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief System Reset
|
||||||
|
\details Initiates a system reset request to reset the MCU.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void NVIC_SystemReset(void)
|
||||||
|
{
|
||||||
|
__DSB(); /* Ensure all outstanding memory accesses included
|
||||||
|
buffered write are completed before reset */
|
||||||
|
SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
|
||||||
|
SCB_AIRCR_SYSRESETREQ_Msk);
|
||||||
|
__DSB(); /* Ensure completion of memory access */
|
||||||
|
|
||||||
|
for(;;) /* wait until reset */
|
||||||
|
{
|
||||||
|
__NOP();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@} end of CMSIS_Core_NVICFunctions */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ################################## SysTick function ############################################ */
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_Core_FunctionInterface
|
||||||
|
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
|
||||||
|
\brief Functions that configure the System.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if (__Vendor_SysTickConfig == 0U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief System Tick Configuration
|
||||||
|
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
|
||||||
|
Counter is in free running mode to generate periodic interrupts.
|
||||||
|
\param [in] ticks Number of ticks between two interrupts.
|
||||||
|
\return 0 Function succeeded.
|
||||||
|
\return 1 Function failed.
|
||||||
|
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
|
||||||
|
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
|
||||||
|
must contain a vendor-specific implementation of this function.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
|
||||||
|
{
|
||||||
|
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
|
||||||
|
{
|
||||||
|
return (1UL); /* Reload value impossible */
|
||||||
|
}
|
||||||
|
|
||||||
|
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
|
||||||
|
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
|
||||||
|
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
|
||||||
|
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
|
||||||
|
SysTick_CTRL_TICKINT_Msk |
|
||||||
|
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
|
||||||
|
return (0UL); /* Function successful */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*@} end of CMSIS_Core_SysTickFunctions */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __CORE_CM0_H_DEPENDANT */
|
||||||
|
|
||||||
|
#endif /* __CMSIS_GENERIC */
|
||||||
@@ -0,0 +1,914 @@
|
|||||||
|
/**************************************************************************//**
|
||||||
|
* @file core_cm0plus.h
|
||||||
|
* @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File
|
||||||
|
* @version V4.30
|
||||||
|
* @date 20. October 2015
|
||||||
|
******************************************************************************/
|
||||||
|
/* Copyright (c) 2009 - 2015 ARM LIMITED
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
to endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
*
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#if defined ( __ICCARM__ )
|
||||||
|
#pragma system_include /* treat file as system include file for MISRA check */
|
||||||
|
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||||
|
#pragma clang system_header /* treat file as system include file */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __CORE_CM0PLUS_H_GENERIC
|
||||||
|
#define __CORE_CM0PLUS_H_GENERIC
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
\page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
|
||||||
|
CMSIS violates the following MISRA-C:2004 rules:
|
||||||
|
|
||||||
|
\li Required Rule 8.5, object/function definition in header file.<br>
|
||||||
|
Function definitions in header files are used to allow 'inlining'.
|
||||||
|
|
||||||
|
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
|
||||||
|
Unions are used for effective representation of core registers.
|
||||||
|
|
||||||
|
\li Advisory Rule 19.7, Function-like macro defined.<br>
|
||||||
|
Function-like macros are used to allow more efficient code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* CMSIS definitions
|
||||||
|
******************************************************************************/
|
||||||
|
/**
|
||||||
|
\ingroup Cortex-M0+
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* CMSIS CM0+ definitions */
|
||||||
|
#define __CM0PLUS_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
|
||||||
|
#define __CM0PLUS_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
|
||||||
|
#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \
|
||||||
|
__CM0PLUS_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
|
||||||
|
|
||||||
|
#define __CORTEX_M (0x00U) /*!< Cortex-M Core */
|
||||||
|
|
||||||
|
|
||||||
|
#if defined ( __CC_ARM )
|
||||||
|
#define __ASM __asm /*!< asm keyword for ARM Compiler */
|
||||||
|
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
|
||||||
|
#define __STATIC_INLINE static __inline
|
||||||
|
|
||||||
|
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||||
|
#define __ASM __asm /*!< asm keyword for ARM Compiler */
|
||||||
|
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
|
||||||
|
#define __STATIC_INLINE static __inline
|
||||||
|
|
||||||
|
#elif defined ( __GNUC__ )
|
||||||
|
#define __ASM __asm /*!< asm keyword for GNU Compiler */
|
||||||
|
#define __INLINE inline /*!< inline keyword for GNU Compiler */
|
||||||
|
#define __STATIC_INLINE static inline
|
||||||
|
|
||||||
|
#elif defined ( __ICCARM__ )
|
||||||
|
#define __ASM __asm /*!< asm keyword for IAR Compiler */
|
||||||
|
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
|
||||||
|
#define __STATIC_INLINE static inline
|
||||||
|
|
||||||
|
#elif defined ( __TMS470__ )
|
||||||
|
#define __ASM __asm /*!< asm keyword for TI CCS Compiler */
|
||||||
|
#define __STATIC_INLINE static inline
|
||||||
|
|
||||||
|
#elif defined ( __TASKING__ )
|
||||||
|
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
|
||||||
|
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
|
||||||
|
#define __STATIC_INLINE static inline
|
||||||
|
|
||||||
|
#elif defined ( __CSMC__ )
|
||||||
|
#define __packed
|
||||||
|
#define __ASM _asm /*!< asm keyword for COSMIC Compiler */
|
||||||
|
#define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
|
||||||
|
#define __STATIC_INLINE static inline
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error Unknown compiler
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** __FPU_USED indicates whether an FPU is used or not.
|
||||||
|
This core does not support an FPU at all
|
||||||
|
*/
|
||||||
|
#define __FPU_USED 0U
|
||||||
|
|
||||||
|
#if defined ( __CC_ARM )
|
||||||
|
#if defined __TARGET_FPU_VFP
|
||||||
|
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||||
|
#if defined __ARM_PCS_VFP
|
||||||
|
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined ( __GNUC__ )
|
||||||
|
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||||
|
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined ( __ICCARM__ )
|
||||||
|
#if defined __ARMVFP__
|
||||||
|
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined ( __TMS470__ )
|
||||||
|
#if defined __TI_VFP_SUPPORT__
|
||||||
|
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined ( __TASKING__ )
|
||||||
|
#if defined __FPU_VFP__
|
||||||
|
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined ( __CSMC__ )
|
||||||
|
#if ( __CSMC__ & 0x400U)
|
||||||
|
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "core_cmInstr.h" /* Core Instruction Access */
|
||||||
|
#include "core_cmFunc.h" /* Core Function Access */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __CORE_CM0PLUS_H_GENERIC */
|
||||||
|
|
||||||
|
#ifndef __CMSIS_GENERIC
|
||||||
|
|
||||||
|
#ifndef __CORE_CM0PLUS_H_DEPENDANT
|
||||||
|
#define __CORE_CM0PLUS_H_DEPENDANT
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* check device defines and use defaults */
|
||||||
|
#if defined __CHECK_DEVICE_DEFINES
|
||||||
|
#ifndef __CM0PLUS_REV
|
||||||
|
#define __CM0PLUS_REV 0x0000U
|
||||||
|
#warning "__CM0PLUS_REV not defined in device header file; using default!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __MPU_PRESENT
|
||||||
|
#define __MPU_PRESENT 0U
|
||||||
|
#warning "__MPU_PRESENT not defined in device header file; using default!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __VTOR_PRESENT
|
||||||
|
#define __VTOR_PRESENT 0U
|
||||||
|
#warning "__VTOR_PRESENT not defined in device header file; using default!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __NVIC_PRIO_BITS
|
||||||
|
#define __NVIC_PRIO_BITS 2U
|
||||||
|
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __Vendor_SysTickConfig
|
||||||
|
#define __Vendor_SysTickConfig 0U
|
||||||
|
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* IO definitions (access restrictions to peripheral registers) */
|
||||||
|
/**
|
||||||
|
\defgroup CMSIS_glob_defs CMSIS Global Defines
|
||||||
|
|
||||||
|
<strong>IO Type Qualifiers</strong> are used
|
||||||
|
\li to specify the access to peripheral variables.
|
||||||
|
\li for automatic generation of peripheral register debug information.
|
||||||
|
*/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define __I volatile /*!< Defines 'read only' permissions */
|
||||||
|
#else
|
||||||
|
#define __I volatile const /*!< Defines 'read only' permissions */
|
||||||
|
#endif
|
||||||
|
#define __O volatile /*!< Defines 'write only' permissions */
|
||||||
|
#define __IO volatile /*!< Defines 'read / write' permissions */
|
||||||
|
|
||||||
|
/* following defines should be used for structure members */
|
||||||
|
#define __IM volatile const /*! Defines 'read only' structure member permissions */
|
||||||
|
#define __OM volatile /*! Defines 'write only' structure member permissions */
|
||||||
|
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
|
||||||
|
|
||||||
|
/*@} end of group Cortex-M0+ */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Register Abstraction
|
||||||
|
Core Register contain:
|
||||||
|
- Core Register
|
||||||
|
- Core NVIC Register
|
||||||
|
- Core SCB Register
|
||||||
|
- Core SysTick Register
|
||||||
|
- Core MPU Register
|
||||||
|
******************************************************************************/
|
||||||
|
/**
|
||||||
|
\defgroup CMSIS_core_register Defines and Type Definitions
|
||||||
|
\brief Type definitions and defines for Cortex-M processor based devices.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_CORE Status and Control Registers
|
||||||
|
\brief Core Register type definitions.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Union type to access the Application Program Status Register (APSR).
|
||||||
|
*/
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
|
||||||
|
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||||
|
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||||
|
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||||
|
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||||
|
} b; /*!< Structure used for bit access */
|
||||||
|
uint32_t w; /*!< Type used for word access */
|
||||||
|
} APSR_Type;
|
||||||
|
|
||||||
|
/* APSR Register Definitions */
|
||||||
|
#define APSR_N_Pos 31U /*!< APSR: N Position */
|
||||||
|
#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
|
||||||
|
|
||||||
|
#define APSR_Z_Pos 30U /*!< APSR: Z Position */
|
||||||
|
#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
|
||||||
|
|
||||||
|
#define APSR_C_Pos 29U /*!< APSR: C Position */
|
||||||
|
#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
|
||||||
|
|
||||||
|
#define APSR_V_Pos 28U /*!< APSR: V Position */
|
||||||
|
#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Union type to access the Interrupt Program Status Register (IPSR).
|
||||||
|
*/
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
|
||||||
|
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
|
||||||
|
} b; /*!< Structure used for bit access */
|
||||||
|
uint32_t w; /*!< Type used for word access */
|
||||||
|
} IPSR_Type;
|
||||||
|
|
||||||
|
/* IPSR Register Definitions */
|
||||||
|
#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
|
||||||
|
#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Union type to access the Special-Purpose Program Status Registers (xPSR).
|
||||||
|
*/
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
|
||||||
|
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
|
||||||
|
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
|
||||||
|
uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
|
||||||
|
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||||
|
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||||
|
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||||
|
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||||
|
} b; /*!< Structure used for bit access */
|
||||||
|
uint32_t w; /*!< Type used for word access */
|
||||||
|
} xPSR_Type;
|
||||||
|
|
||||||
|
/* xPSR Register Definitions */
|
||||||
|
#define xPSR_N_Pos 31U /*!< xPSR: N Position */
|
||||||
|
#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
|
||||||
|
|
||||||
|
#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
|
||||||
|
#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
|
||||||
|
|
||||||
|
#define xPSR_C_Pos 29U /*!< xPSR: C Position */
|
||||||
|
#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
|
||||||
|
|
||||||
|
#define xPSR_V_Pos 28U /*!< xPSR: V Position */
|
||||||
|
#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
|
||||||
|
|
||||||
|
#define xPSR_T_Pos 24U /*!< xPSR: T Position */
|
||||||
|
#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
|
||||||
|
|
||||||
|
#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
|
||||||
|
#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Union type to access the Control Registers (CONTROL).
|
||||||
|
*/
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
|
||||||
|
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
|
||||||
|
uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
|
||||||
|
} b; /*!< Structure used for bit access */
|
||||||
|
uint32_t w; /*!< Type used for word access */
|
||||||
|
} CONTROL_Type;
|
||||||
|
|
||||||
|
/* CONTROL Register Definitions */
|
||||||
|
#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
|
||||||
|
#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
|
||||||
|
|
||||||
|
#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */
|
||||||
|
#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_CORE */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
|
||||||
|
\brief Type definitions for the NVIC Registers
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
|
||||||
|
uint32_t RESERVED0[31U];
|
||||||
|
__IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
|
||||||
|
uint32_t RSERVED1[31U];
|
||||||
|
__IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
|
||||||
|
uint32_t RESERVED2[31U];
|
||||||
|
__IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
|
||||||
|
uint32_t RESERVED3[31U];
|
||||||
|
uint32_t RESERVED4[64U];
|
||||||
|
__IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
|
||||||
|
} NVIC_Type;
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_NVIC */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_SCB System Control Block (SCB)
|
||||||
|
\brief Type definitions for the System Control Block Registers
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Structure type to access the System Control Block (SCB).
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
|
||||||
|
__IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
|
||||||
|
#if (__VTOR_PRESENT == 1U)
|
||||||
|
__IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
|
||||||
|
#else
|
||||||
|
uint32_t RESERVED0;
|
||||||
|
#endif
|
||||||
|
__IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
|
||||||
|
__IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
|
||||||
|
__IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
|
||||||
|
uint32_t RESERVED1;
|
||||||
|
__IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
|
||||||
|
__IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
|
||||||
|
} SCB_Type;
|
||||||
|
|
||||||
|
/* SCB CPUID Register Definitions */
|
||||||
|
#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
|
||||||
|
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
|
||||||
|
|
||||||
|
#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
|
||||||
|
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
|
||||||
|
|
||||||
|
#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
|
||||||
|
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
|
||||||
|
|
||||||
|
#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
|
||||||
|
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
|
||||||
|
|
||||||
|
#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
|
||||||
|
#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
|
||||||
|
|
||||||
|
/* SCB Interrupt Control State Register Definitions */
|
||||||
|
#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
|
||||||
|
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
|
||||||
|
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
|
||||||
|
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
|
||||||
|
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
|
||||||
|
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
|
||||||
|
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
|
||||||
|
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
|
||||||
|
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
|
||||||
|
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
|
||||||
|
|
||||||
|
#if (__VTOR_PRESENT == 1U)
|
||||||
|
/* SCB Interrupt Control State Register Definitions */
|
||||||
|
#define SCB_VTOR_TBLOFF_Pos 8U /*!< SCB VTOR: TBLOFF Position */
|
||||||
|
#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* SCB Application Interrupt and Reset Control Register Definitions */
|
||||||
|
#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
|
||||||
|
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
|
||||||
|
|
||||||
|
#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
|
||||||
|
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
|
||||||
|
|
||||||
|
#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
|
||||||
|
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
|
||||||
|
|
||||||
|
#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
|
||||||
|
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
|
||||||
|
|
||||||
|
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
|
||||||
|
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
|
||||||
|
|
||||||
|
/* SCB System Control Register Definitions */
|
||||||
|
#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
|
||||||
|
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
|
||||||
|
|
||||||
|
#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
|
||||||
|
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
|
||||||
|
|
||||||
|
#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
|
||||||
|
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
|
||||||
|
|
||||||
|
/* SCB Configuration Control Register Definitions */
|
||||||
|
#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
|
||||||
|
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
|
||||||
|
|
||||||
|
#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
|
||||||
|
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
|
||||||
|
|
||||||
|
/* SCB System Handler Control and State Register Definitions */
|
||||||
|
#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
|
||||||
|
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_SCB */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
|
||||||
|
\brief Type definitions for the System Timer Registers.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Structure type to access the System Timer (SysTick).
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
|
||||||
|
__IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
|
||||||
|
__IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
|
||||||
|
__IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
|
||||||
|
} SysTick_Type;
|
||||||
|
|
||||||
|
/* SysTick Control / Status Register Definitions */
|
||||||
|
#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
|
||||||
|
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
|
||||||
|
|
||||||
|
#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
|
||||||
|
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
|
||||||
|
|
||||||
|
#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
|
||||||
|
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
|
||||||
|
|
||||||
|
#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
|
||||||
|
#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
|
||||||
|
|
||||||
|
/* SysTick Reload Register Definitions */
|
||||||
|
#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
|
||||||
|
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
|
||||||
|
|
||||||
|
/* SysTick Current Register Definitions */
|
||||||
|
#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
|
||||||
|
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
|
||||||
|
|
||||||
|
/* SysTick Calibration Register Definitions */
|
||||||
|
#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
|
||||||
|
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
|
||||||
|
|
||||||
|
#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
|
||||||
|
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
|
||||||
|
|
||||||
|
#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
|
||||||
|
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_SysTick */
|
||||||
|
|
||||||
|
#if (__MPU_PRESENT == 1U)
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_MPU Memory Protection Unit (MPU)
|
||||||
|
\brief Type definitions for the Memory Protection Unit (MPU)
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Structure type to access the Memory Protection Unit (MPU).
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
|
||||||
|
__IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
|
||||||
|
__IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
|
||||||
|
__IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
|
||||||
|
__IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
|
||||||
|
} MPU_Type;
|
||||||
|
|
||||||
|
/* MPU Type Register Definitions */
|
||||||
|
#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
|
||||||
|
#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
|
||||||
|
|
||||||
|
#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */
|
||||||
|
#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
|
||||||
|
|
||||||
|
#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */
|
||||||
|
#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */
|
||||||
|
|
||||||
|
/* MPU Control Register Definitions */
|
||||||
|
#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */
|
||||||
|
#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
|
||||||
|
|
||||||
|
#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */
|
||||||
|
#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
|
||||||
|
|
||||||
|
#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */
|
||||||
|
#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */
|
||||||
|
|
||||||
|
/* MPU Region Number Register Definitions */
|
||||||
|
#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */
|
||||||
|
#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */
|
||||||
|
|
||||||
|
/* MPU Region Base Address Register Definitions */
|
||||||
|
#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */
|
||||||
|
#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
|
||||||
|
|
||||||
|
#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */
|
||||||
|
#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
|
||||||
|
|
||||||
|
#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */
|
||||||
|
#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */
|
||||||
|
|
||||||
|
/* MPU Region Attribute and Size Register Definitions */
|
||||||
|
#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */
|
||||||
|
#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
|
||||||
|
|
||||||
|
#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */
|
||||||
|
#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
|
||||||
|
|
||||||
|
#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */
|
||||||
|
#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
|
||||||
|
|
||||||
|
#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */
|
||||||
|
#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
|
||||||
|
|
||||||
|
#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */
|
||||||
|
#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
|
||||||
|
|
||||||
|
#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */
|
||||||
|
#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
|
||||||
|
|
||||||
|
#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */
|
||||||
|
#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
|
||||||
|
|
||||||
|
#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */
|
||||||
|
#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
|
||||||
|
|
||||||
|
#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */
|
||||||
|
#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
|
||||||
|
|
||||||
|
#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */
|
||||||
|
#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_MPU */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
|
||||||
|
\brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
|
||||||
|
Therefore they are not covered by the Cortex-M0+ header file.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
/*@} end of group CMSIS_CoreDebug */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_core_bitfield Core register bit field macros
|
||||||
|
\brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Mask and shift a bit field value for use in a register bit range.
|
||||||
|
\param[in] field Name of the register bit field.
|
||||||
|
\param[in] value Value of the bit field.
|
||||||
|
\return Masked and shifted value.
|
||||||
|
*/
|
||||||
|
#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Mask and shift a register value to extract a bit filed value.
|
||||||
|
\param[in] field Name of the register bit field.
|
||||||
|
\param[in] value Value of register.
|
||||||
|
\return Masked and shifted bit field value.
|
||||||
|
*/
|
||||||
|
#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_core_bitfield */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_core_base Core Definitions
|
||||||
|
\brief Definitions for base addresses, unions, and structures.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Memory mapping of Cortex-M0+ Hardware */
|
||||||
|
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
|
||||||
|
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
|
||||||
|
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
|
||||||
|
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
|
||||||
|
|
||||||
|
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
|
||||||
|
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
|
||||||
|
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
|
||||||
|
|
||||||
|
#if (__MPU_PRESENT == 1U)
|
||||||
|
#define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
|
||||||
|
#define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*@} */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Hardware Abstraction Layer
|
||||||
|
Core Function Interface contains:
|
||||||
|
- Core NVIC Functions
|
||||||
|
- Core SysTick Functions
|
||||||
|
- Core Register Access Functions
|
||||||
|
******************************************************************************/
|
||||||
|
/**
|
||||||
|
\defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ########################## NVIC functions #################################### */
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_Core_FunctionInterface
|
||||||
|
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
|
||||||
|
\brief Functions that manage interrupts and exceptions via the NVIC.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Interrupt Priorities are WORD accessible only under ARMv6M */
|
||||||
|
/* The following MACROS handle generation of the register offset and byte masks */
|
||||||
|
#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
|
||||||
|
#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
|
||||||
|
#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Enable External Interrupt
|
||||||
|
\details Enables a device-specific interrupt in the NVIC interrupt controller.
|
||||||
|
\param [in] IRQn External interrupt number. Value cannot be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Disable External Interrupt
|
||||||
|
\details Disables a device-specific interrupt in the NVIC interrupt controller.
|
||||||
|
\param [in] IRQn External interrupt number. Value cannot be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Pending Interrupt
|
||||||
|
\details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
|
||||||
|
\param [in] IRQn Interrupt number.
|
||||||
|
\return 0 Interrupt status is not pending.
|
||||||
|
\return 1 Interrupt status is pending.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Pending Interrupt
|
||||||
|
\details Sets the pending bit of an external interrupt.
|
||||||
|
\param [in] IRQn Interrupt number. Value cannot be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Clear Pending Interrupt
|
||||||
|
\details Clears the pending bit of an external interrupt.
|
||||||
|
\param [in] IRQn External interrupt number. Value cannot be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Interrupt Priority
|
||||||
|
\details Sets the priority of an interrupt.
|
||||||
|
\note The priority cannot be set for every core interrupt.
|
||||||
|
\param [in] IRQn Interrupt number.
|
||||||
|
\param [in] priority Priority to set.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
|
||||||
|
{
|
||||||
|
if ((int32_t)(IRQn) < 0)
|
||||||
|
{
|
||||||
|
SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||||
|
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||||
|
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Interrupt Priority
|
||||||
|
\details Reads the priority of an interrupt.
|
||||||
|
The interrupt number can be positive to specify an external (device specific) interrupt,
|
||||||
|
or negative to specify an internal (core) interrupt.
|
||||||
|
\param [in] IRQn Interrupt number.
|
||||||
|
\return Interrupt Priority.
|
||||||
|
Value is aligned automatically to the implemented priority bits of the microcontroller.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ((int32_t)(IRQn) < 0)
|
||||||
|
{
|
||||||
|
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief System Reset
|
||||||
|
\details Initiates a system reset request to reset the MCU.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void NVIC_SystemReset(void)
|
||||||
|
{
|
||||||
|
__DSB(); /* Ensure all outstanding memory accesses included
|
||||||
|
buffered write are completed before reset */
|
||||||
|
SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
|
||||||
|
SCB_AIRCR_SYSRESETREQ_Msk);
|
||||||
|
__DSB(); /* Ensure completion of memory access */
|
||||||
|
|
||||||
|
for(;;) /* wait until reset */
|
||||||
|
{
|
||||||
|
__NOP();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@} end of CMSIS_Core_NVICFunctions */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ################################## SysTick function ############################################ */
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_Core_FunctionInterface
|
||||||
|
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
|
||||||
|
\brief Functions that configure the System.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if (__Vendor_SysTickConfig == 0U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief System Tick Configuration
|
||||||
|
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
|
||||||
|
Counter is in free running mode to generate periodic interrupts.
|
||||||
|
\param [in] ticks Number of ticks between two interrupts.
|
||||||
|
\return 0 Function succeeded.
|
||||||
|
\return 1 Function failed.
|
||||||
|
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
|
||||||
|
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
|
||||||
|
must contain a vendor-specific implementation of this function.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
|
||||||
|
{
|
||||||
|
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
|
||||||
|
{
|
||||||
|
return (1UL); /* Reload value impossible */
|
||||||
|
}
|
||||||
|
|
||||||
|
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
|
||||||
|
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
|
||||||
|
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
|
||||||
|
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
|
||||||
|
SysTick_CTRL_TICKINT_Msk |
|
||||||
|
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
|
||||||
|
return (0UL); /* Function successful */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*@} end of CMSIS_Core_SysTickFunctions */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __CORE_CM0PLUS_H_DEPENDANT */
|
||||||
|
|
||||||
|
#endif /* __CMSIS_GENERIC */
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,87 @@
|
|||||||
|
/**************************************************************************//**
|
||||||
|
* @file core_cmFunc.h
|
||||||
|
* @brief CMSIS Cortex-M Core Function Access Header File
|
||||||
|
* @version V4.30
|
||||||
|
* @date 20. October 2015
|
||||||
|
******************************************************************************/
|
||||||
|
/* Copyright (c) 2009 - 2015 ARM LIMITED
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
- Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
to endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
*
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#if defined ( __ICCARM__ )
|
||||||
|
#pragma system_include /* treat file as system include file for MISRA check */
|
||||||
|
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||||
|
#pragma clang system_header /* treat file as system include file */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __CORE_CMFUNC_H
|
||||||
|
#define __CORE_CMFUNC_H
|
||||||
|
|
||||||
|
|
||||||
|
/* ########################### Core Function Access ########################### */
|
||||||
|
/** \ingroup CMSIS_Core_FunctionInterface
|
||||||
|
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*------------------ RealView Compiler -----------------*/
|
||||||
|
#if defined ( __CC_ARM )
|
||||||
|
#include "cmsis_armcc.h"
|
||||||
|
|
||||||
|
/*------------------ ARM Compiler V6 -------------------*/
|
||||||
|
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||||
|
#include "cmsis_armcc_V6.h"
|
||||||
|
|
||||||
|
/*------------------ GNU Compiler ----------------------*/
|
||||||
|
#elif defined ( __GNUC__ )
|
||||||
|
#include "cmsis_gcc.h"
|
||||||
|
|
||||||
|
/*------------------ ICC Compiler ----------------------*/
|
||||||
|
#elif defined ( __ICCARM__ )
|
||||||
|
#include <cmsis_iar.h>
|
||||||
|
|
||||||
|
/*------------------ TI CCS Compiler -------------------*/
|
||||||
|
#elif defined ( __TMS470__ )
|
||||||
|
#include <cmsis_ccs.h>
|
||||||
|
|
||||||
|
/*------------------ TASKING Compiler ------------------*/
|
||||||
|
#elif defined ( __TASKING__ )
|
||||||
|
/*
|
||||||
|
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||||
|
* Please use "carm -?i" to get an up to date list of all intrinsics,
|
||||||
|
* Including the CMSIS ones.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*------------------ COSMIC Compiler -------------------*/
|
||||||
|
#elif defined ( __CSMC__ )
|
||||||
|
#include <cmsis_csm.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*@} end of CMSIS_Core_RegAccFunctions */
|
||||||
|
|
||||||
|
#endif /* __CORE_CMFUNC_H */
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user