Simple USBHost library for Nucleo F446RE/F411RE/F401RE FRDM-KL46Z/KL25Z/F64F LPC4088/LPC1768

Dependencies:   FATFileSystem

Dependents:   F401RE-BTstack_example F401RE-USBHostMSD_HelloWorld

Fork of KL46Z-USBHost by Norimasa Okamoto

簡易USBホストライブラリです。
official-USBHostの下位互換で対応プログラムを僅かな修正で動かすことが出来ます。

Platforms

  • Nucleo F446RE
  • Nucleo F411RE
  • Nucleo F401RE
  • FRDM-K64F
  • FRDM-KL46Z
  • FRDM-KL25Z
  • LPC4088
  • LPC1768

Nucleo F446RE/F411RE/F401REのUSB接続方法

ST morphoUSB
U5V (CN10-8)VBUS (1 RED)
PA11 (CN10-14)DM  (2 WHITE)
PA12 (CN10-12)DP  (3 GREEN)
GND (CN10-20)GND (4 BLACK)

Examples

Import programF446RE-USBHostMouse_HelloWorld

USBHostMouse Hello World for ST-Nucleo-F446RE

Import programF401RE-USBHostMSD_HelloWorld

Simple USBHost MSD(USB flash drive) for Nucleo F401RE/FRDM-KL46Z test program

Import programF401RE-USBHostC270_example

Simple USBHost WebCam test program

Import programK64F_USBHostC270_example

Simple USBHost C270 example

Import programF401RE-BTstack_example

BTstack for Nucleo F401RE/FRDM-KL46Z example program

Import programUSBHostRSSI_example

Bluetooth device discovery example program.

Import programKL46Z-USBHostGPS_HelloWorld

Simple USBHost GPS Dongle Receiver for FRDM-KL46Z test program

Committer:
va009039
Date:
Thu Jan 23 08:32:54 2014 +0000
Revision:
2:0cdac6bcc534
add retry in token transfer

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 2:0cdac6bcc534 1 // Simple USBHost for FRDM-KL46Z
va009039 2:0cdac6bcc534 2 #include "USBHALHost.h"
va009039 2:0cdac6bcc534 3 #include <algorithm>
va009039 2:0cdac6bcc534 4
va009039 2:0cdac6bcc534 5 template <bool>struct CtAssert;
va009039 2:0cdac6bcc534 6 template <>struct CtAssert<true> {};
va009039 2:0cdac6bcc534 7 #define CTASSERT(A) CtAssert<A>();
va009039 2:0cdac6bcc534 8
va009039 2:0cdac6bcc534 9
va009039 2:0cdac6bcc534 10 #ifdef _USB_DBG
va009039 2:0cdac6bcc534 11 #define USB_DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");} while(0);
va009039 2:0cdac6bcc534 12 #define USB_DBG_HEX(A,B) debug_hex(A,B)
va009039 2:0cdac6bcc534 13 void debug_hex(uint8_t* buf, int size);
va009039 2:0cdac6bcc534 14 #else
va009039 2:0cdac6bcc534 15 #define USB_DBG(...) while(0)
va009039 2:0cdac6bcc534 16 #define USB_DBG_HEX(A,B) while(0)
va009039 2:0cdac6bcc534 17 #endif
va009039 2:0cdac6bcc534 18
va009039 2:0cdac6bcc534 19 #define USB_TEST_ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);};
va009039 2:0cdac6bcc534 20 #define USB_TEST_ASSERT_FALSE(A) USB_TEST_ASSERT(!(A))
va009039 2:0cdac6bcc534 21
va009039 2:0cdac6bcc534 22 #define BD_OWN_MASK (1<<7)
va009039 2:0cdac6bcc534 23 #define BD_DATA01_MASK (1<<6)
va009039 2:0cdac6bcc534 24 #define BD_KEEP_MASK (1<<5)
va009039 2:0cdac6bcc534 25 #define BD_NINC_MASK (1<<4)
va009039 2:0cdac6bcc534 26 #define BD_DTS_MASK (1<<3)
va009039 2:0cdac6bcc534 27 #define BD_STALL_MASK (1<<2)
va009039 2:0cdac6bcc534 28
va009039 2:0cdac6bcc534 29 #define TX 1
va009039 2:0cdac6bcc534 30 #define RX 0
va009039 2:0cdac6bcc534 31
va009039 2:0cdac6bcc534 32 #define EP0_BDT_IDX(dir, odd) (((2 * dir) + (1 * odd)))
va009039 2:0cdac6bcc534 33
va009039 2:0cdac6bcc534 34 #define SETUP_TOKEN 0x0D
va009039 2:0cdac6bcc534 35 #define IN_TOKEN 0x09
va009039 2:0cdac6bcc534 36 #define OUT_TOKEN 0x01
va009039 2:0cdac6bcc534 37
va009039 2:0cdac6bcc534 38 // for each endpt: 8 bytes
va009039 2:0cdac6bcc534 39 struct BDT {
va009039 2:0cdac6bcc534 40 uint8_t info; // BD[0:7]
va009039 2:0cdac6bcc534 41 uint8_t dummy; // RSVD: BD[8:15]
va009039 2:0cdac6bcc534 42 uint16_t byte_count; // BD[16:32]
va009039 2:0cdac6bcc534 43 uint32_t address; // Addr
va009039 2:0cdac6bcc534 44 void setBuffer(uint8_t* buf, int size) {
va009039 2:0cdac6bcc534 45 address = (uint32_t)buf;
va009039 2:0cdac6bcc534 46 byte_count = size;
va009039 2:0cdac6bcc534 47 }
va009039 2:0cdac6bcc534 48 uint8_t getStatus() {
va009039 2:0cdac6bcc534 49 return (info>>2)&0x0f;
va009039 2:0cdac6bcc534 50 }
va009039 2:0cdac6bcc534 51 };
va009039 2:0cdac6bcc534 52
va009039 2:0cdac6bcc534 53 __attribute__((__aligned__(512))) BDT bdt[64];
va009039 2:0cdac6bcc534 54
va009039 2:0cdac6bcc534 55 USBHALHost* USBHALHost::instHost;
va009039 2:0cdac6bcc534 56
va009039 2:0cdac6bcc534 57 USBHALHost::USBHALHost() {
va009039 2:0cdac6bcc534 58 instHost = this;
va009039 2:0cdac6bcc534 59 memset(rx_data01, DATA1, sizeof(rx_data01));
va009039 2:0cdac6bcc534 60 memset(tx_data01, DATA1, sizeof(tx_data01));
va009039 2:0cdac6bcc534 61 }
va009039 2:0cdac6bcc534 62
va009039 2:0cdac6bcc534 63 void USBHALHost::init() {
va009039 2:0cdac6bcc534 64 // Disable IRQ
va009039 2:0cdac6bcc534 65 NVIC_DisableIRQ(USB0_IRQn);
va009039 2:0cdac6bcc534 66
va009039 2:0cdac6bcc534 67 // choose usb src as PLL
va009039 2:0cdac6bcc534 68 SIM->SOPT2 |= (SIM_SOPT2_USBSRC_MASK | SIM_SOPT2_PLLFLLSEL_MASK);
va009039 2:0cdac6bcc534 69
va009039 2:0cdac6bcc534 70 // enable OTG clock
va009039 2:0cdac6bcc534 71 SIM->SCGC4 |= SIM_SCGC4_USBOTG_MASK;
va009039 2:0cdac6bcc534 72
va009039 2:0cdac6bcc534 73 // USB Module Configuration
va009039 2:0cdac6bcc534 74 // Reset USB Module
va009039 2:0cdac6bcc534 75 USB0->USBTRC0 |= USB_USBTRC0_USBRESET_MASK;
va009039 2:0cdac6bcc534 76 while(USB0->USBTRC0 & USB_USBTRC0_USBRESET_MASK);
va009039 2:0cdac6bcc534 77
va009039 2:0cdac6bcc534 78 // Clear interrupt flag
va009039 2:0cdac6bcc534 79 USB0->ISTAT = 0xff;
va009039 2:0cdac6bcc534 80
va009039 2:0cdac6bcc534 81 // Set BDT Base Register
va009039 2:0cdac6bcc534 82 USB0->BDTPAGE1=(uint8_t)((uint32_t)bdt>>8);
va009039 2:0cdac6bcc534 83 USB0->BDTPAGE2=(uint8_t)((uint32_t)bdt>>16);
va009039 2:0cdac6bcc534 84 USB0->BDTPAGE3=(uint8_t)((uint32_t)bdt>>24);
va009039 2:0cdac6bcc534 85
va009039 2:0cdac6bcc534 86 // Set SOF threshold
va009039 2:0cdac6bcc534 87 USB0->SOFTHLD = USB_SOFTHLD_CNT(1);
va009039 2:0cdac6bcc534 88
va009039 2:0cdac6bcc534 89 // pulldown D+ and D-
va009039 2:0cdac6bcc534 90 USB0->USBCTRL = USB_USBCTRL_PDE_MASK;
va009039 2:0cdac6bcc534 91
va009039 2:0cdac6bcc534 92 USB0->USBTRC0 |= 0x40;
va009039 2:0cdac6bcc534 93
va009039 2:0cdac6bcc534 94 // Host mode
va009039 2:0cdac6bcc534 95 USB0->CTL |= USB_CTL_HOSTMODEEN_MASK;
va009039 2:0cdac6bcc534 96 // Desable SOF packet generation
va009039 2:0cdac6bcc534 97 USB0->CTL &= ~USB_CTL_USBENSOFEN_MASK;
va009039 2:0cdac6bcc534 98
va009039 2:0cdac6bcc534 99 NVIC_SetVector(USB0_IRQn, (uint32_t)_usbisr);
va009039 2:0cdac6bcc534 100 NVIC_EnableIRQ(USB0_IRQn);
va009039 2:0cdac6bcc534 101
va009039 2:0cdac6bcc534 102 wait_attach();
va009039 2:0cdac6bcc534 103
va009039 2:0cdac6bcc534 104 for(int retry = 2; retry > 0; retry--) {
va009039 2:0cdac6bcc534 105 // Enable RESET
va009039 2:0cdac6bcc534 106 USB0->CTL |= USB_CTL_RESET_MASK;
va009039 2:0cdac6bcc534 107 wait_ms(500);
va009039 2:0cdac6bcc534 108 USB0->CTL &= ~USB_CTL_RESET_MASK;
va009039 2:0cdac6bcc534 109
va009039 2:0cdac6bcc534 110 // Enable SOF
va009039 2:0cdac6bcc534 111 USB0->CTL |= USB_CTL_USBENSOFEN_MASK;
va009039 2:0cdac6bcc534 112 wait_ms(100);
va009039 2:0cdac6bcc534 113
va009039 2:0cdac6bcc534 114 // token transfer initialize
va009039 2:0cdac6bcc534 115 tx_ptr = ODD;
va009039 2:0cdac6bcc534 116 rx_ptr = ODD;
va009039 2:0cdac6bcc534 117 USB0->INTEN |= USB_INTEN_TOKDNEEN_MASK;
va009039 2:0cdac6bcc534 118
va009039 2:0cdac6bcc534 119 if (enumeration()) {
va009039 2:0cdac6bcc534 120 break;
va009039 2:0cdac6bcc534 121 }
va009039 2:0cdac6bcc534 122 USB_DBG("retry=%d", retry);
va009039 2:0cdac6bcc534 123 USB_TEST_ASSERT(retry > 1);
va009039 2:0cdac6bcc534 124 }
va009039 2:0cdac6bcc534 125 }
va009039 2:0cdac6bcc534 126
va009039 2:0cdac6bcc534 127 void USBHALHost::wait_attach() {
va009039 2:0cdac6bcc534 128 attach_done = false;
va009039 2:0cdac6bcc534 129 USB0->INTEN = USB_INTEN_ATTACHEN_MASK;
va009039 2:0cdac6bcc534 130 while(!attach_done);
va009039 2:0cdac6bcc534 131 wait_ms(100);
va009039 2:0cdac6bcc534 132 USB_TEST_ASSERT_FALSE(USB0->CTL & USB_CTL_SE0_MASK);
va009039 2:0cdac6bcc534 133 lowSpeed = (USB0->CTL & USB_CTL_JSTATE_MASK) ? false : true;
va009039 2:0cdac6bcc534 134 if (lowSpeed) { // low speed
va009039 2:0cdac6bcc534 135 USB0->ENDPOINT[0].ENDPT |= USB_ENDPT_HOSTWOHUB_MASK;
va009039 2:0cdac6bcc534 136 }
va009039 2:0cdac6bcc534 137 USB_DBG("lowSpeed=%d", lowSpeed);
va009039 2:0cdac6bcc534 138 }
va009039 2:0cdac6bcc534 139
va009039 2:0cdac6bcc534 140 void USBHALHost::setAddr(int _addr) {
va009039 2:0cdac6bcc534 141 USB0->ADDR = (lowSpeed ? USB_ADDR_LSEN_MASK : 0x00) | USB_ADDR_ADDR(_addr);
va009039 2:0cdac6bcc534 142 }
va009039 2:0cdac6bcc534 143
va009039 2:0cdac6bcc534 144 void USBHALHost::setEndpoint(bool use_retry) {
va009039 2:0cdac6bcc534 145 USB0->ENDPOINT[0].ENDPT = (lowSpeed ? USB_ENDPT_HOSTWOHUB_MASK : 0x00)|
va009039 2:0cdac6bcc534 146 USB_ENDPT_EPCTLDIS_MASK|
va009039 2:0cdac6bcc534 147 (use_retry ? 0x00 : USB_ENDPT_RETRYDIS_MASK)|
va009039 2:0cdac6bcc534 148 USB_ENDPT_EPRXEN_MASK|
va009039 2:0cdac6bcc534 149 USB_ENDPT_EPTXEN_MASK|
va009039 2:0cdac6bcc534 150 USB_ENDPT_EPHSHK_MASK;
va009039 2:0cdac6bcc534 151 }
va009039 2:0cdac6bcc534 152
va009039 2:0cdac6bcc534 153 int USBHALHost::token_setup(SETUP_PACKET* setup, uint16_t wLength) {
va009039 2:0cdac6bcc534 154 int retry = 0;
va009039 2:0cdac6bcc534 155 do {
va009039 2:0cdac6bcc534 156 token_ready();
va009039 2:0cdac6bcc534 157 USB0->ENDPOINT[0].ENDPT = (lowSpeed ? USB_ENDPT_HOSTWOHUB_MASK : 0x00) |
va009039 2:0cdac6bcc534 158 USB_ENDPT_RETRYDIS_MASK|
va009039 2:0cdac6bcc534 159 USB_ENDPT_EPRXEN_MASK|
va009039 2:0cdac6bcc534 160 USB_ENDPT_EPTXEN_MASK|
va009039 2:0cdac6bcc534 161 USB_ENDPT_EPHSHK_MASK;
va009039 2:0cdac6bcc534 162 CTASSERT(sizeof(SETUP_PACKET) == 8);
va009039 2:0cdac6bcc534 163 setup->wLength = wLength;
va009039 2:0cdac6bcc534 164 int idx = EP0_BDT_IDX(TX, tx_ptr);
va009039 2:0cdac6bcc534 165 bdt[idx].setBuffer((uint8_t*)setup, sizeof(SETUP_PACKET));
va009039 2:0cdac6bcc534 166 bdt[idx].info = BD_OWN_MASK |
va009039 2:0cdac6bcc534 167 BD_DTS_MASK; // always data0
va009039 2:0cdac6bcc534 168 token_done = false;
va009039 2:0cdac6bcc534 169 USB0->TOKEN = USB_TOKEN_TOKENPID(SETUP_TOKEN)|USB_TOKEN_TOKENENDPT(0);
va009039 2:0cdac6bcc534 170 while(!token_done);
va009039 2:0cdac6bcc534 171 LastStatus = bdt[idx].getStatus();
va009039 2:0cdac6bcc534 172 if (LastStatus == ACK) {
va009039 2:0cdac6bcc534 173 if (retry > 0) {
va009039 2:0cdac6bcc534 174 USB_DBG("retry=%d %02x", retry, prev_LastStatus);
va009039 2:0cdac6bcc534 175 }
va009039 2:0cdac6bcc534 176 return ACK;
va009039 2:0cdac6bcc534 177 }
va009039 2:0cdac6bcc534 178 wait_ms(1);
va009039 2:0cdac6bcc534 179 prev_LastStatus = LastStatus;
va009039 2:0cdac6bcc534 180 //USB_DBG("retry=%d %02x", retry, prev_LastStatus);
va009039 2:0cdac6bcc534 181 }while(retry++ < 10);
va009039 2:0cdac6bcc534 182 return LastStatus;
va009039 2:0cdac6bcc534 183 }
va009039 2:0cdac6bcc534 184
va009039 2:0cdac6bcc534 185 int USBHALHost::token_in(uint8_t ep, uint8_t* data, int size, int retryLimit) {
va009039 2:0cdac6bcc534 186 USB_TEST_ASSERT(ep < sizeof(rx_data01));
va009039 2:0cdac6bcc534 187 for(int retry = 0;; retry++) {
va009039 2:0cdac6bcc534 188 token_ready();
va009039 2:0cdac6bcc534 189 int idx = EP0_BDT_IDX(RX, rx_ptr);
va009039 2:0cdac6bcc534 190 bdt[idx].setBuffer(data, size);
va009039 2:0cdac6bcc534 191 bdt[idx].info = BD_OWN_MASK|
va009039 2:0cdac6bcc534 192 BD_DTS_MASK|
va009039 2:0cdac6bcc534 193 ((rx_data01[ep] == DATA1) ? BD_DATA01_MASK : 0);
va009039 2:0cdac6bcc534 194 token_done = false;
va009039 2:0cdac6bcc534 195 USB0->TOKEN = USB_TOKEN_TOKENPID(IN_TOKEN)|USB_TOKEN_TOKENENDPT(ep);
va009039 2:0cdac6bcc534 196 while(!token_done);
va009039 2:0cdac6bcc534 197 LastStatus = bdt[idx].getStatus();
va009039 2:0cdac6bcc534 198 int len = bdt[idx].byte_count;
va009039 2:0cdac6bcc534 199 if (LastStatus == DATA0 || LastStatus == DATA1) {
va009039 2:0cdac6bcc534 200 rx_data01[ep] = LastStatus == DATA0 ? DATA1 : DATA0;
va009039 2:0cdac6bcc534 201 if (retry > 0) {
va009039 2:0cdac6bcc534 202 USB_DBG("len=%d retry=%d %02x", len, retry, prev_LastStatus);
va009039 2:0cdac6bcc534 203 }
va009039 2:0cdac6bcc534 204 return len;
va009039 2:0cdac6bcc534 205 }
va009039 2:0cdac6bcc534 206 if (++retry >= retryLimit) {
va009039 2:0cdac6bcc534 207 return -1;
va009039 2:0cdac6bcc534 208 }
va009039 2:0cdac6bcc534 209 wait_ms(100);
va009039 2:0cdac6bcc534 210 prev_LastStatus = LastStatus;
va009039 2:0cdac6bcc534 211 }
va009039 2:0cdac6bcc534 212 }
va009039 2:0cdac6bcc534 213
va009039 2:0cdac6bcc534 214 int USBHALHost::token_out(uint8_t ep, const uint8_t* data, int size) {
va009039 2:0cdac6bcc534 215 USB_TEST_ASSERT(ep < sizeof(tx_data01));
va009039 2:0cdac6bcc534 216 int retry = 0;
va009039 2:0cdac6bcc534 217 do {
va009039 2:0cdac6bcc534 218 token_ready();
va009039 2:0cdac6bcc534 219 int idx = EP0_BDT_IDX(TX, tx_ptr);
va009039 2:0cdac6bcc534 220 bdt[idx].info = BD_OWN_MASK|
va009039 2:0cdac6bcc534 221 BD_DTS_MASK|
va009039 2:0cdac6bcc534 222 ((tx_data01[ep] == DATA1) ? BD_DATA01_MASK : 0);
va009039 2:0cdac6bcc534 223 bdt[idx].setBuffer((uint8_t*)data, size);
va009039 2:0cdac6bcc534 224 token_done = false;
va009039 2:0cdac6bcc534 225 USB0->TOKEN = USB_TOKEN_TOKENPID(OUT_TOKEN)|USB_TOKEN_TOKENENDPT(ep);
va009039 2:0cdac6bcc534 226 while(!token_done);
va009039 2:0cdac6bcc534 227 LastStatus = bdt[idx].getStatus();
va009039 2:0cdac6bcc534 228 if (LastStatus == ACK) {
va009039 2:0cdac6bcc534 229 tx_data01[ep] = (tx_data01[ep] == DATA0) ? DATA1 : DATA0;
va009039 2:0cdac6bcc534 230 if (retry > 0) {
va009039 2:0cdac6bcc534 231 USB_DBG("retry=%d %02x", retry, prev_LastStatus);
va009039 2:0cdac6bcc534 232 }
va009039 2:0cdac6bcc534 233 return bdt[idx].byte_count;
va009039 2:0cdac6bcc534 234 }
va009039 2:0cdac6bcc534 235 wait_ms(10);
va009039 2:0cdac6bcc534 236 prev_LastStatus = LastStatus;
va009039 2:0cdac6bcc534 237 } while(retry++ < 10);
va009039 2:0cdac6bcc534 238 return -1;
va009039 2:0cdac6bcc534 239 }
va009039 2:0cdac6bcc534 240
va009039 2:0cdac6bcc534 241 void USBHALHost::token_ready() {
va009039 2:0cdac6bcc534 242 while(USB0->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) { // TOKEN_BUSY ?
va009039 2:0cdac6bcc534 243 wait_ms(1);
va009039 2:0cdac6bcc534 244 }
va009039 2:0cdac6bcc534 245 USB0->ISTAT |= USB_ISTAT_SOFTOK_MASK; // Clear SOF
va009039 2:0cdac6bcc534 246 while (!(USB0->ISTAT & USB_ISTAT_SOFTOK_MASK));
va009039 2:0cdac6bcc534 247 USB0->SOFTHLD = 0; // this is needed as without this you can get errors
va009039 2:0cdac6bcc534 248 USB0->ISTAT |= USB_ISTAT_SOFTOK_MASK; // clear SOF
va009039 2:0cdac6bcc534 249 }
va009039 2:0cdac6bcc534 250
va009039 2:0cdac6bcc534 251 void USBHALHost::_usbisr(void) {
va009039 2:0cdac6bcc534 252 if (instHost) {
va009039 2:0cdac6bcc534 253 instHost->UsbIrqhandler();
va009039 2:0cdac6bcc534 254 }
va009039 2:0cdac6bcc534 255 }
va009039 2:0cdac6bcc534 256
va009039 2:0cdac6bcc534 257 void USBHALHost::UsbIrqhandler() {
va009039 2:0cdac6bcc534 258 uint8_t istat = USB0->ISTAT;
va009039 2:0cdac6bcc534 259 if (istat & USB_ISTAT_TOKDNE_MASK) {
va009039 2:0cdac6bcc534 260 uint8_t stat = USB0->STAT;
va009039 2:0cdac6bcc534 261 ODD_EVEN next_ptr = (stat & USB_STAT_ODD_MASK) ? ODD : EVEN;
va009039 2:0cdac6bcc534 262 if (stat & USB_STAT_TX_MASK) {
va009039 2:0cdac6bcc534 263 tx_ptr = next_ptr;
va009039 2:0cdac6bcc534 264 } else {
va009039 2:0cdac6bcc534 265 rx_ptr = next_ptr;
va009039 2:0cdac6bcc534 266 }
va009039 2:0cdac6bcc534 267 token_done = true;
va009039 2:0cdac6bcc534 268 }
va009039 2:0cdac6bcc534 269 if (istat & USB_ISTAT_ATTACH_MASK) {
va009039 2:0cdac6bcc534 270 USB0->INTEN &= ~USB_INTEN_ATTACHEN_MASK;
va009039 2:0cdac6bcc534 271 attach_done = true;
va009039 2:0cdac6bcc534 272 }
va009039 2:0cdac6bcc534 273 USB0->ISTAT = istat; // clear
va009039 2:0cdac6bcc534 274 }
va009039 2:0cdac6bcc534 275
va009039 2:0cdac6bcc534 276 void debug_hex(uint8_t* buf, int size) {
va009039 2:0cdac6bcc534 277 for(int i = 0; i < size; i++) {
va009039 2:0cdac6bcc534 278 fprintf(stderr, "%02x ", buf[i]);
va009039 2:0cdac6bcc534 279 if (i%16 == 15) {
va009039 2:0cdac6bcc534 280 fprintf(stderr, "\r\n");
va009039 2:0cdac6bcc534 281 }
va009039 2:0cdac6bcc534 282 }
va009039 2:0cdac6bcc534 283 fprintf(stderr, "\r\n");
va009039 2:0cdac6bcc534 284 }
va009039 2:0cdac6bcc534 285