uint32 ICACHE_FLASH_ATTR RdMdbData(smdbadu * mdbbuf, uint32 addr, uint32 len) { if (mdbbuf->id != 0) { // if(len > 125) return MDBERRDATA; mdbiosize = (len << 1) + 3; // полный размер ADU mdbbuf->out.cnt = (uint8) (len << 1); // размер блока данных в байтах uint8 * wbuf; wbuf = (uint8 *) mdbbuf->out.data; // указатель на данные ответа mdb (для записи) smdbtabaddr * ptr; ptr = (smdbtabaddr *) &mdbtabaddr[0]; // указатель на первую структуру в таблице do { while (addr > ptr->addre) ptr++; if (ptr->addrs == 0xFFFF) return MDBERRADDR; // не найден if (addr < ptr->addrs) return MDBERRADDR; // не найден uint32 i = ptr->addre - addr + 1; // размерчик пересылки в этом блоке if (len < i) i = len; // больше чем запрос? -> ограничить uint8 * rbuf; // входной буфер (или адрес в блоке, если в таблице buf=null) rbuf = &ptr->buf[(addr - ptr->addrs)<<1]; // расчитать указатель на данные uint32 x; if (ptr->func) { if ((x = ptr->func(wbuf, rbuf, i)) != MDBERRNO) return x; } else { // Если NULL -> функция не вызывается if (ptr->buf) { // данные передаются из блока приема? if ((x = MdbWordRW(wbuf, rbuf, i)) != MDBERRNO) return x; } else { x = i; uint8 * p = wbuf; while(x--) { *p++ = 0; *p++ = 0; } os_memset(wbuf, 0, i << 1); // передать нули } }; len -= i; // вычесть кол-во данных этой пересылки addr += i; // шаг адреса wbuf += i << 1; // шаг в блоке выходных данных ответа mdb ptr++; // на следюший указатель в таблице } while (len); Swapws(&mdbbuf->out.data[0], mdbbuf->out.cnt >> 1); } else
uint32 ICACHE_FLASH_ATTR RdMdbData(uint8 * wbuf, uint16 addr, uint32 len) { #if DEBUGSOO > 3 os_printf("mdbrd:%u[%u]\n", addr, len); #endif smdbtabaddr * ptr = (smdbtabaddr *) &mdbtabaddr[0]; // указатель на первую структуру в таблице do { while (addr > ptr->addre) ptr++; if (ptr->addrs == 0xFFFF) return MDBERRADDR; // не найден if (addr < ptr->addrs) return MDBERRADDR; // не найден uint32 i = ptr->addre - addr + 1; // размерчик пересылки в этом блоке if (len < i) i = len; // больше чем запрос? -> ограничить uint8 * rbuf; // входной буфер (или адрес в блоке, если в таблице buf=null) rbuf = &ptr->buf[(addr - ptr->addrs)<<1]; // расчитать указатель на данные uint32 x; if (ptr->func) { if ((x = ptr->func(wbuf, rbuf, i)) != MDBERRNO) return x; } else { // Если NULL -> функция не вызывается if (ptr->buf) { // данные передаются из блока приема? if ((x = MdbWordRW(wbuf, rbuf, i)) != MDBERRNO) return x; } else { x = i; uint8 * p = wbuf; while(x--) { *p++ = 0; *p++ = 0; } os_memset(wbuf, 0, i << 1); // передать нули } }; len -= i; // вычесть кол-во данных этой пересылки addr += i; // шаг адреса wbuf += i << 1; // шаг в блоке выходных данных ответа mdb ptr++; // на следюший указатель в таблице } while (len); return MDBERRNO; }