#include "samplering.h" static const char * const hexstr = "0123456789ABCDEF"; uint32_t SampleRing::Up (const char * data, const uint32_t len) { for (unsigned n=0; n= '0') and (c <= '9')) { result += (unsigned) (c - '0'); } else if ((c >= 'A') and (c <= 'F')) { result += (unsigned) (c - 'A' + 10); } else if ((c >= 'a') and (c <= 'f')) { result += (unsigned) (c - 'a' + 10); } else { // chyba : nech byt } } CommandPass (result); } void SampleRing::CommandPass(const unsigned int cmd) { RcvdHeader header; header.common = cmd & 0xFFFF; const DESTINATION dest = static_cast (header.bits.destinat); switch (dest) { case DEST_CHA: case DEST_CHB: break; case DEST_BASE: ReloadTimer (header.bits.cmd_value); break; case DEST_TRIG: { const TRIGGER_CMD command = static_cast (header.bits.cmd_type); switch (command) { case TRIGGER_CMD_OFSET: m_settings.offset = header.bits.cmd_value; break; case TRIGGER_CMD_VALUE: m_settings.value = header.bits.cmd_value; break; case TRIGGER_CMD_MODE: { TriggerModeUnion new_mode_union; new_mode_union.common = header.bits.cmd_value; const TRIGER_MODE new_mode = static_cast (new_mode_union.bits.mode); if (m_settings.mode != new_mode) m_settings.mode = new_mode; const ADC_CHANNELS new_channel = static_cast(new_mode_union.bits.channel); if (m_settings.channel != new_channel) m_settings.channel = new_channel; const bool new_rising = new_mode_union.bits.rissing ? true : false; if (m_settings.rising != new_rising) m_settings.rising = new_rising; } break; } } break; } } void SampleRing::write(DATA_BLOCK const * data) { if (m_finished) return; unsigned t_head = m_head; // dočasné proměnné kvůli zrychlení unsigned t_lenght = m_lenght; // následujícího cyklu if (m_mode == TIME_BASE_TRIGERED) { for (unsigned n=0u; n m_settings.value); if (compare and m_old_triger and !m_trigered) { // TRIGERED if (t_lenght >= m_settings.offset) { t_lenght = m_settings.offset; m_trigered = true; } } m_old_triger = !compare; if (t_lenght >= RING_LEN) { // zastavit odesílání dat, pokud není AUTO a není splněna podmínka trigeru if ((m_settings.mode != TRIGER_MODE_AUTO) and !m_trigered) continue; t_lenght = RING_LEN; m_tail = t_head; m_finished = true; break; } } } else { const DATA_BLOCK & sample = data [0]; ring_buffer [t_head].common_data = sample.common_data; t_head += 1u; t_head &= RING_MSK; t_lenght += 1u; m_finished = true; } m_head = t_head; // vrať zpátky hodnoty m_lenght = t_lenght; } bool SampleRing::read(DATA_BLOCK & sample) { if (!m_finished) return false; if (!m_lenght) { m_head = m_tail = m_lenght = 0u; m_trigered = false; m_finished = false; return false; } sample = ring_buffer [m_tail]; m_tail += 1u; m_tail &= RING_MSK; m_lenght -= 1u; return true; } uint32_t SampleRing::BlockSend (const char * buf, const uint32_t len) { uint32_t n, ofs = 0, req = len; for (;;) { // spodní vrstva může vrátit i nulu, pokud je FIFO plné n = BaseLayer::Down (buf + ofs, req); ofs += n; // Posuneme ukazatel req -= n; // Zmenšíme další požadavek if (!req) break; } return ofs; } void SampleRing::pass() { if (!m_finished) { return; } SendPrefix(); DATA_BLOCK data; while (read(data)) { SendData (data); } BlockSend("\r\n", 2); } static int to_str (char * buffer, const uint16_t data, const int len = 3) { unsigned val = data; for (int i=len-1; i>=0; --i) { buffer [i] = hexstr [val & 0xF]; val >>= 4; } return len; } uint32_t SampleRing::SendPrefix() { const int buflen = 8; char buffer [buflen]; int n = 0; buffer [n++] = '$'; SendHeader sh; sh.bits.trig_flg = m_trigered ? 1 : 0; sh.bits.pack_len = m_lenght; n += to_str (buffer + n, sh.common, 4); buffer [n++] = '#'; return BlockSend (buffer, n); } uint32_t SampleRing::SendData (const DATA_BLOCK & data) { const int buflen = 8; char buffer [buflen]; int n = 0; n += to_str (buffer + n, data.channels[0]); n += to_str (buffer + n, data.channels[1]); return BlockSend (buffer, n); }