⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modem.cpp

📁 C++ modem驱动代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/** * FSKFilter */FSKFilter::FSKFilter(int type)    : m_fskStarted(-1),    m_lastFiltered(0),    m_processed(0),    m_accSin(0),    m_bitSamples(0){    switch (type) {	case FSKModem::ETSI:	    break;	default:	    return;    }    m_index = 0;    m_const = s_filterConst + type;    // Update the sine accumulator from constants (current value after created the header)    m_accSin = m_const->accSin;    m_mark.init(1+m_const->spb);    m_space.init(1+m_const->spb);    m_lowband.init(1+m_const->spb);}// Process data to demodulate a bit// Return negative if buffer ended, 0/1 if found a bitinline int FSKFilter::getBit(short*& samples, unsigned int& len){    float ds = m_const->bitLen / 32.;    bool transition = false;    while (len) {	float filtered = filter(samples,len);	// Check if this a bit transition	if (filtered * m_lastFiltered < 0 && !transition) {	    if (m_processed < m_const->halfBitLen)		m_processed += ds;	    else		m_processed -= ds;	    transition = true;	}	m_lastFiltered = filtered;	m_processed += 1.;	// Processed a bit: adjust clock (bit length) and return the result	if (m_processed > m_const->bitLen) {	    m_processed -= m_const->bitLen;	    return filtered > 0 ? 1 : 0;;	}    }    return -1;}// Filter data until a start bit is found (used to wait for FSK modulation to start)// Return true if a start bit is found, false if all buffer was processed with no resultinline bool FSKFilter::waitFSK(short*& samples, unsigned int& len){    if (fskStarted())	return true;    if (!len)	return false;    float tmp = 0;    if (m_fskStarted == -1) {	while (tmp >= -0.5) {	    if (!len)		return false;	    tmp = filter(samples,len);	}	m_fskStarted = 0;    }    // Wait for 0.5 bits before starting the demodulation    tmp = 1;    while (tmp > 0) {	if (len < m_const->halfSpb)	    return false;	for(unsigned int i = m_const->halfSpb; i; i--)	    tmp = filter(samples,len);    }    m_fskStarted = 1;    return true;}// Add a modulated bit to a destination bufferinline void FSKFilter::addBit(short* samples, unsigned int& index, bool bit){    // Get the number of samples nedded for this bit and advance the index    unsigned int n = m_const->timingSamples(m_bitSamples);    // Build and store the modulated samples    if (bit)	for(; n; n--) {	    m_accSin += m_const->markCoef;	    samples[index++] = (short)(MARK_AMPLITUDE * sin(m_accSin));	}    else	for(; n; n--) {	    m_accSin += m_const->spaceCoef;	    samples[index++] = (short)(SPACE_AMPLITUDE * sin(m_accSin));	}}// Modulate data to a buffer// dataBits must not be 0 or greater then 8// full=true: add data bytes (start bit + data + stop bit)double FSKFilter::addBuffer(DataBlock& dest, const DataBlock& src,	unsigned char dataBits, bool full){    // Calculate the destination length. Add 2 more bits if full    if (m_const)	if (full)	    dest.assign(0,m_const->bufLen(src.length() * (dataBits + 2)) * sizeof(short));	else	    dest.assign(0,m_const->bufLen(src.length() * dataBits) * sizeof(short));    else	dest.clear();    if (!dest.length())	return m_accSin;    // Build modulated buffer    unsigned char* srcData = (unsigned char*)(src.data());    short* destData = (short*)(dest.data());    unsigned int index = 0;    if (full)	for (unsigned int i = 0; i < src.length(); i++)	    addByteFull(destData,index,srcData[i],dataBits);    else	for (unsigned int i = 0; i < src.length(); i++)	    addByte(destData,index,srcData[i],dataBits);    return m_accSin;}// Apply mark/space and low band filterinline float FSKFilter::filter(short*& samples, unsigned int& len){#define SPB m_const->spb#define MOD(val) ((val) & SPB)    short sample = *samples++;    len--;    // Mark filter    m_mark.xbuf[MOD(m_index+6)] = sample * m_const->markGain;    float mark = m_mark.xbuf[MOD(m_index+6)] - m_mark.xbuf[m_index]	+ 3 * (m_mark.xbuf[MOD(m_index+2)] - m_mark.xbuf[MOD(m_index+4)]);    for (unsigned int i = 0; i < 6; i++)	mark += m_mark.ybuf[MOD(m_index+i)] * m_const->mark[i];    m_mark.ybuf[MOD(m_index+6)] = mark;    // Space filter    m_space.xbuf[MOD(m_index+6)] = sample * m_const->spaceGain;    float space = m_space.xbuf[MOD(m_index+6)] - m_space.xbuf[m_index]	+ 3 * (m_space.xbuf[MOD(m_index+2)] - m_space.xbuf[MOD(m_index+4)]);    for (unsigned int i = 0; i < 6; i++)	space += m_space.ybuf[MOD(m_index+i)] * m_const->space[i];    m_space.ybuf[MOD(m_index+6)] = space;    // Low band filter    float result = mark * mark - space * space;    m_lowband.xbuf[MOD(m_index+6)] = result * m_const->lowbandGain;    result =    (m_lowband.xbuf[m_index]        + m_lowband.xbuf[MOD(m_index+6)])	 + 6  * (m_lowband.xbuf[MOD(m_index+1)] + m_lowband.xbuf[MOD(m_index+5)])	 + 15 * (m_lowband.xbuf[MOD(m_index+2)] + m_lowband.xbuf[MOD(m_index+4)])	 + 20 *  m_lowband.xbuf[MOD(m_index+3)];    for (unsigned int i = 0; i < 6; i++)	result += m_lowband.ybuf[MOD(m_index+i)] * m_const->lowband[i];    m_lowband.ybuf[MOD(m_index+6)] = result;    // Increase index    m_index = MOD(m_index+1);#undef SPB#undef MOD    return result;}/** * FSKModem */TokenDict FSKModem::s_typeName[] = {    {"etsi", FSKModem::ETSI},    {0,0}};FSKModem::FSKModem(const NamedList& params, UART* uart)    : m_type(ETSI),    m_terminated(false),    m_filter(0),    m_uart(uart),    m_bits(0){    if (!m_uart) {	Debug(DebugWarn,"Request to create FSK modem without UART");	m_terminated = true;	return;    }    const char* typeName = params.getValue("modemtype");    if (typeName && *typeName)	m_type = lookup(typeName,s_typeName);    switch (m_type) {	case ETSI:	    break;	default:	    Debug(m_uart,DebugWarn,"Unknown modem type='%s' [%p]",typeName,m_uart);	    m_terminated = true;	    return;    }#ifdef YMODEM_BUFFER_BITS    if (params.getBoolValue("bufferbits",false))	m_bits = new BitBuffer;#endif    reset();    XDebug(m_uart,DebugAll,"Modem created type='%s' [%p]",lookup(m_type,s_typeName),this);}FSKModem::~FSKModem(){    if (m_filter)	delete m_filter;    if (m_bits) {	m_bits->printBits(m_uart);	delete m_bits;    }    XDebug(m_uart,DebugAll,"Modem destroyed [%p]",this);}// Reset state. Clear buffervoid FSKModem::reset(){    m_terminated = false;    m_buffer.clear();    if (m_filter)	delete m_filter;    m_filter = 0;    if (m_type < TypeCount)	m_filter = new FSKFilter(m_type);    if (m_bits)	m_bits->reset();}// Data processor. Feed the collector// Return false to stop processingbool FSKModem::demodulate(const DataBlock& data){    if (m_terminated)	return false;    if (!data.length())	return true;    // Prepare buffer to process    void* buffer = 0;                    // Original buffer    unsigned int len = 0;                // Data length in bytes    if (m_buffer.length()) {	m_buffer += data;	buffer = m_buffer.data();	len = m_buffer.length();    }    else {	buffer = data.data();	len = data.length();    }    short* samples = (short*)buffer;          // Data to process    unsigned int count = len / sizeof(short); // The number of available samples    XDebug(m_uart,DebugAll,"Demodulating %u bytes [%p]",len,m_uart);    // Wait at least 6 samples to process    while (count > 6) {	// Check if FSK modulation was detected	if (!m_filter->fskStarted()) {	    if (!m_filter->waitFSK(samples,count))		break;	    DDebug(m_uart,DebugInfo,"FSK modulation started [%p]",m_uart);	    m_terminated = !m_uart->fskStarted();	    if (m_terminated)		break;#ifdef YMODEM_BUFFER_BITS	    if (m_bits)		m_bits->accumulate(false);#endif	    m_terminated = !m_uart->recvBit(false);	}	// FSK started: get bits and send them to the UART	for (int bit = 1; bit >= 0 && !m_terminated; ) {	    bit = m_filter->getBit(samples,count);	    if (bit >= 0) {#ifdef YMODEM_BUFFER_BITS		if (m_bits)		    m_bits->accumulate(bit);#endif		m_terminated = !m_uart->recvBit(bit);	    }	}	break;    }    // Keep the unprocessed bytes    unsigned int rest = count * sizeof(short) + len % sizeof(short);    if (rest) {	DataBlock tmp;	if (m_buffer.data()) {	   tmp.assign(buffer,len,false);	   m_buffer.clear(false);	}	m_buffer.assign(samples,rest);    }    else	m_buffer.clear();    return !m_terminated;}// Create a buffer containing the modulated representation of a messagevoid FSKModem::modulate(DataBlock& dest, const DataBlock& data){#ifdef DEBUG    String tmp;    tmp.hexify(data.data(),data.length(),' ');    Debug(m_uart,DebugAll,"Modulating '%s' [%p]",tmp.safe(),m_uart);#endif    if (!(data.length() && m_filter && m_filter->constants()))	return;    DataBlock tmpData;    m_filter->addBuffer(tmpData,data,m_uart->accumulator().dataBits(),true);    dest += m_filter->constants()->header;    dest += tmpData;    // Build pattern after    unsigned int nbits = (unsigned int)(m_filter->constants()->baudRate / 1000 * PATTERN_AFTER);    DataBlock p(0,(nbits+7)/8);    DataBlock tmpAfter;    m_filter->addBuffer(tmpAfter,p,m_uart->accumulator().dataBits(),false);    dest += tmpAfter;    DDebug(m_uart,DebugAll,"Modulated header=%u data=%u pattern=%u [%p]",	m_filter->constants()->header.length(),	tmpData.length(),tmpAfter.length(),m_uart);}/* vi: set ts=8 sw=4 sts=4 noet: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -