convert JPEG stream data to bitmap, BaseJpegDecode example program

Dependencies:   BaseJpegDecode BaseUsbHost FATFileSystem mbed-rtos mbed

JPEGデコードのサンプルプログラムです。
JPEGのMCU単位で逐次デコード出力していますので少ないRAMメモリで動かすことが出来ます。

#include "USBHostMSD.h"
#include "SimpleJpegDecode.h"
#include "bmp24.h"

const char* INPUT_FILE  = "/usb/input.jpg";
const char* OUTPUT_FILE = "/usb/output.bmp";

bmp24 bmp;
RawSerial pc(USBTX, USBRX);

void callbackRGB(int x, int y, uint8_t* rgb) {
    bmp.point(x, y, rgb);
    pc.printf("x=%d, y=%d, RGB=(0x%02x,0x%02x,0x%02x)\n", x, y, rgb[0], rgb[1], rgb[2]);
}

int main() {
    pc.baud(115200);
    
    USBHostMSD* msd = new USBHostMSD("usb");
    if (!msd->connect()) {
        error("USB Flash drive not found.\n");
    } 
    SimpleJpegDecode* decode = new SimpleJpegDecode(RGB24);

    decode->setOnResult(callbackRGB);
    decode->clear();
    pc.printf("input: %s\n", INPUT_FILE);
    FILE* fp = fopen(INPUT_FILE, "rb");
    if (fp == NULL) {
         error("open error\n");
    }
    while(1) {
        int c = fgetc(fp);
        if (c == EOF) {
            break;
        }
        decode->input(c);
    }
    fclose(fp);
    pc.printf("output: %s\n", OUTPUT_FILE);
    if (!bmp.writeFile(OUTPUT_FILE)) {
        error("write error\n");
    }
    exit(1);     
}
Committer:
va009039
Date:
Sat Feb 02 01:25:25 2013 +0000
Revision:
0:98f918e1d528
first commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 0:98f918e1d528 1 // UsbFlashDrive.cpp 2013/1/25
va009039 0:98f918e1d528 2 #include "mbed.h"
va009039 0:98f918e1d528 3 #include "rtos.h"
va009039 0:98f918e1d528 4 #include "BaseUsbHost.h"
va009039 0:98f918e1d528 5 //#define DEBUG
va009039 0:98f918e1d528 6 #include "BaseUsbHostDebug.h"
va009039 0:98f918e1d528 7 #define TEST
va009039 0:98f918e1d528 8 #include "BaseUsbHostTest.h"
va009039 0:98f918e1d528 9 #include "UsbFlashDrive.h"
va009039 0:98f918e1d528 10
va009039 0:98f918e1d528 11 //#define WRITE_PROTECT
va009039 0:98f918e1d528 12
va009039 0:98f918e1d528 13
va009039 0:98f918e1d528 14 uint32_t BE32(uint8_t* d)
va009039 0:98f918e1d528 15 {
va009039 0:98f918e1d528 16 return (d[0] << 24) | (d[1] << 16) | (d[2] << 8) | d[3];
va009039 0:98f918e1d528 17 }
va009039 0:98f918e1d528 18
va009039 0:98f918e1d528 19 void BE16(uint32_t n, uint8_t* d)
va009039 0:98f918e1d528 20 {
va009039 0:98f918e1d528 21 d[0] = (uint8_t)(n >> 8);
va009039 0:98f918e1d528 22 d[1] = (uint8_t)n;
va009039 0:98f918e1d528 23 }
va009039 0:98f918e1d528 24
va009039 0:98f918e1d528 25 void BE32(uint32_t n, uint8_t* d)
va009039 0:98f918e1d528 26 {
va009039 0:98f918e1d528 27 d[0] = (uint8_t)(n >> 24);
va009039 0:98f918e1d528 28 d[1] = (uint8_t)(n >> 16);
va009039 0:98f918e1d528 29 d[2] = (uint8_t)(n >> 8);
va009039 0:98f918e1d528 30 d[3] = (uint8_t)n;
va009039 0:98f918e1d528 31 }
va009039 0:98f918e1d528 32
va009039 0:98f918e1d528 33 UsbFlashDrive::UsbFlashDrive(const char* name, ControlEp* ctlEp): FATFileSystem(name)
va009039 0:98f918e1d528 34 {
va009039 0:98f918e1d528 35 m_name = name;
va009039 0:98f918e1d528 36
va009039 0:98f918e1d528 37 if (ctlEp == NULL) { // root hub
va009039 0:98f918e1d528 38 DBG_OHCI(LPC_USB->HcRhPortStatus1);
va009039 0:98f918e1d528 39 TEST_ASSERT_FALSE(LPC_USB->HcRhPortStatus1 & 0x200);
va009039 0:98f918e1d528 40 ctlEp = new ControlEp();
va009039 0:98f918e1d528 41 TEST_ASSERT_TRUE(ctlEp);
va009039 0:98f918e1d528 42 }
va009039 0:98f918e1d528 43
va009039 0:98f918e1d528 44 CTASSERT(sizeof(CBW) == 31);
va009039 0:98f918e1d528 45 CTASSERT(sizeof(CSW) == 13);
va009039 0:98f918e1d528 46 TEST_ASSERT(sizeof(CBW) == 31);
va009039 0:98f918e1d528 47 TEST_ASSERT(sizeof(CSW) == 13);
va009039 0:98f918e1d528 48
va009039 0:98f918e1d528 49 m_numBlocks = 0;
va009039 0:98f918e1d528 50 m_BlockSize = 0;
va009039 0:98f918e1d528 51 m_lun = 0;
va009039 0:98f918e1d528 52 m_interface = 0;
va009039 0:98f918e1d528 53 m_pEpBulkIn = NULL;
va009039 0:98f918e1d528 54 m_pEpBulkOut = NULL;
va009039 0:98f918e1d528 55
va009039 0:98f918e1d528 56 ParseConfiguration(ctlEp);
va009039 0:98f918e1d528 57 int rc = ctlEp->SetConfiguration(1);
va009039 0:98f918e1d528 58 TEST_ASSERT_EQUAL(rc, USB_OK);
va009039 0:98f918e1d528 59 GetMaxLUN(ctlEp);
va009039 0:98f918e1d528 60 setup(ctlEp);
va009039 0:98f918e1d528 61 }
va009039 0:98f918e1d528 62
va009039 0:98f918e1d528 63 bool UsbFlashDrive::check(ControlEp* ctlEp)
va009039 0:98f918e1d528 64 {
va009039 0:98f918e1d528 65 if (ctlEp == NULL) {
va009039 0:98f918e1d528 66 return false;
va009039 0:98f918e1d528 67 }
va009039 0:98f918e1d528 68 CTASSERT(sizeof(StandardDeviceDescriptor) == 18);
va009039 0:98f918e1d528 69 CTASSERT(sizeof(StandardConfigurationDescriptor) == 9);
va009039 0:98f918e1d528 70 CTASSERT(sizeof(StandardInterfaceDescriptor) == 9);
va009039 0:98f918e1d528 71 TEST_ASSERT(sizeof(StandardDeviceDescriptor) == 18);
va009039 0:98f918e1d528 72 TEST_ASSERT(sizeof(StandardConfigurationDescriptor) == 9);
va009039 0:98f918e1d528 73 TEST_ASSERT(sizeof(StandardInterfaceDescriptor) == 9);
va009039 0:98f918e1d528 74
va009039 0:98f918e1d528 75 StandardDeviceDescriptor desc;
va009039 0:98f918e1d528 76 int rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_DEVICE, 0, reinterpret_cast<uint8_t*>(&desc), sizeof(StandardDeviceDescriptor));
va009039 0:98f918e1d528 77 if (rc != USB_OK) {
va009039 0:98f918e1d528 78 return false;
va009039 0:98f918e1d528 79 }
va009039 0:98f918e1d528 80 if (desc.bDeviceClass == 8) {
va009039 0:98f918e1d528 81 return true;
va009039 0:98f918e1d528 82 } else if (desc.bDeviceClass != 0x00) {
va009039 0:98f918e1d528 83 return false;
va009039 0:98f918e1d528 84 }
va009039 0:98f918e1d528 85 uint8_t temp[4];
va009039 0:98f918e1d528 86 rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, temp, sizeof(temp));
va009039 0:98f918e1d528 87 if (rc != USB_OK) {
va009039 0:98f918e1d528 88 return false;
va009039 0:98f918e1d528 89 }
va009039 0:98f918e1d528 90 StandardConfigurationDescriptor* cfg = reinterpret_cast<StandardConfigurationDescriptor*>(temp);
va009039 0:98f918e1d528 91 uint8_t* buf = new uint8_t[cfg->wTotalLength];
va009039 0:98f918e1d528 92
va009039 0:98f918e1d528 93 rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, buf, cfg->wTotalLength);
va009039 0:98f918e1d528 94 if (rc != USB_OK) {
va009039 0:98f918e1d528 95 return false;
va009039 0:98f918e1d528 96 }
va009039 0:98f918e1d528 97 DBG_HEX(buf, cfg->wTotalLength);
va009039 0:98f918e1d528 98 bool ret = false;
va009039 0:98f918e1d528 99 for(int pos = 0; pos < cfg->wTotalLength; pos += buf[pos]) {
va009039 0:98f918e1d528 100 StandardInterfaceDescriptor* desc = reinterpret_cast<StandardInterfaceDescriptor*>(buf+pos);
va009039 0:98f918e1d528 101 if (desc->bDescriptorType == 4) { // interface ?
va009039 0:98f918e1d528 102 if (desc->bInterfaceClass == 8 && desc->bInterfaceSubClass == 6 && desc->bInterfaceProtocol == 0x50) {
va009039 0:98f918e1d528 103 ret = true;
va009039 0:98f918e1d528 104 }
va009039 0:98f918e1d528 105 break;
va009039 0:98f918e1d528 106 }
va009039 0:98f918e1d528 107 }
va009039 0:98f918e1d528 108 delete[] buf;
va009039 0:98f918e1d528 109 return ret;
va009039 0:98f918e1d528 110 }
va009039 0:98f918e1d528 111
va009039 0:98f918e1d528 112 int UsbFlashDrive::disk_initialize()
va009039 0:98f918e1d528 113 {
va009039 0:98f918e1d528 114 //DBG("m_BlockSize=%d\n", m_BlockSize);
va009039 0:98f918e1d528 115 if (m_BlockSize != 512) {
va009039 0:98f918e1d528 116 return 1;
va009039 0:98f918e1d528 117 }
va009039 0:98f918e1d528 118 return 0;
va009039 0:98f918e1d528 119 }
va009039 0:98f918e1d528 120
va009039 0:98f918e1d528 121 int UsbFlashDrive::disk_write(const uint8_t* buffer, uint64_t sector)
va009039 0:98f918e1d528 122 {
va009039 0:98f918e1d528 123 m_report_disk_write++;
va009039 0:98f918e1d528 124 //DBG("buffer=%p block_number=%d\n", buffer, sector);
va009039 0:98f918e1d528 125 int ret = MS_BulkSend(sector, 1, buffer);
va009039 0:98f918e1d528 126 if (ret >= 0) {
va009039 0:98f918e1d528 127 return 0;
va009039 0:98f918e1d528 128 }
va009039 0:98f918e1d528 129 return 1;
va009039 0:98f918e1d528 130 }
va009039 0:98f918e1d528 131
va009039 0:98f918e1d528 132 int UsbFlashDrive::disk_read(uint8_t* buffer, uint64_t sector)
va009039 0:98f918e1d528 133 {
va009039 0:98f918e1d528 134 m_report_disk_read++;
va009039 0:98f918e1d528 135 //DBG("buffer=%p block_number=%d\n", buffer, sector);
va009039 0:98f918e1d528 136 int ret = MS_BulkRecv(sector, 1, buffer);
va009039 0:98f918e1d528 137 if (ret >= 0) {
va009039 0:98f918e1d528 138 return 0;
va009039 0:98f918e1d528 139 }
va009039 0:98f918e1d528 140 return 1;
va009039 0:98f918e1d528 141 }
va009039 0:98f918e1d528 142
va009039 0:98f918e1d528 143 int UsbFlashDrive::disk_status()
va009039 0:98f918e1d528 144 {
va009039 0:98f918e1d528 145 m_report_disk_status++;
va009039 0:98f918e1d528 146 return 0;
va009039 0:98f918e1d528 147 }
va009039 0:98f918e1d528 148
va009039 0:98f918e1d528 149 int UsbFlashDrive::disk_sync()
va009039 0:98f918e1d528 150 {
va009039 0:98f918e1d528 151 m_report_disk_sync++;
va009039 0:98f918e1d528 152 return 0;
va009039 0:98f918e1d528 153 }
va009039 0:98f918e1d528 154
va009039 0:98f918e1d528 155 uint64_t UsbFlashDrive::disk_sectors()
va009039 0:98f918e1d528 156 {
va009039 0:98f918e1d528 157 DBG("m_numBlocks=%d\n", m_numBlocks);
va009039 0:98f918e1d528 158 return m_numBlocks;
va009039 0:98f918e1d528 159 }
va009039 0:98f918e1d528 160
va009039 0:98f918e1d528 161 int UsbFlashDrive::setup(ControlEp* ctlEp, int timeout)
va009039 0:98f918e1d528 162 {
va009039 0:98f918e1d528 163
va009039 0:98f918e1d528 164 int retry = 0;
va009039 0:98f918e1d528 165 Timer t;
va009039 0:98f918e1d528 166 t.start();
va009039 0:98f918e1d528 167 t.reset();
va009039 0:98f918e1d528 168 while(t.read_ms() < timeout) {
va009039 0:98f918e1d528 169 DBG("retry=%d t=%d\n", retry, t.read_ms());
va009039 0:98f918e1d528 170 if (retry > 80) {
va009039 0:98f918e1d528 171 return -1;
va009039 0:98f918e1d528 172 }
va009039 0:98f918e1d528 173 int rc = TestUnitReady();
va009039 0:98f918e1d528 174 DBG("TestUnitReady(): %d\n", rc);
va009039 0:98f918e1d528 175 if (rc == USB_OK) {
va009039 0:98f918e1d528 176 DBG("m_CSW.bCSWStatus: %02X\n", m_CSW.bCSWStatus);
va009039 0:98f918e1d528 177 if (m_CSW.bCSWStatus == 0x00) {
va009039 0:98f918e1d528 178 break;
va009039 0:98f918e1d528 179 }
va009039 0:98f918e1d528 180 }
va009039 0:98f918e1d528 181 GetSenseInfo();
va009039 0:98f918e1d528 182 retry++;
va009039 0:98f918e1d528 183 wait_ms(50);
va009039 0:98f918e1d528 184 }
va009039 0:98f918e1d528 185 if (t.read_ms() >= timeout) {
va009039 0:98f918e1d528 186 return -1;
va009039 0:98f918e1d528 187 }
va009039 0:98f918e1d528 188 ReadCapacity();
va009039 0:98f918e1d528 189 Inquire();
va009039 0:98f918e1d528 190 return 0;
va009039 0:98f918e1d528 191 }
va009039 0:98f918e1d528 192
va009039 0:98f918e1d528 193 int UsbFlashDrive::ParseConfiguration(ControlEp* ctlEp)
va009039 0:98f918e1d528 194 {
va009039 0:98f918e1d528 195 TEST_ASSERT(ctlEp);
va009039 0:98f918e1d528 196 TEST_ASSERT(sizeof(StandardEndpointDescriptor) == 7);
va009039 0:98f918e1d528 197 uint8_t temp[4];
va009039 0:98f918e1d528 198 int rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, temp, sizeof(temp));
va009039 0:98f918e1d528 199 if (rc != USB_OK) {
va009039 0:98f918e1d528 200 return rc;
va009039 0:98f918e1d528 201 }
va009039 0:98f918e1d528 202 StandardConfigurationDescriptor* cfg = reinterpret_cast<StandardConfigurationDescriptor*>(temp);
va009039 0:98f918e1d528 203 uint8_t* buf = new uint8_t[cfg->wTotalLength];
va009039 0:98f918e1d528 204 rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, buf, cfg->wTotalLength);
va009039 0:98f918e1d528 205 if (rc != USB_OK) {
va009039 0:98f918e1d528 206 return rc;
va009039 0:98f918e1d528 207 }
va009039 0:98f918e1d528 208 DBG_HEX(buf, cfg->wTotalLength);
va009039 0:98f918e1d528 209 for(int pos = 0; pos < cfg->wTotalLength; pos += buf[pos]) {
va009039 0:98f918e1d528 210 StandardEndpointDescriptor* desc = reinterpret_cast<StandardEndpointDescriptor*>(buf+pos);
va009039 0:98f918e1d528 211 if (desc->bDescriptorType == USB_DESCRIPTOR_TYPE_ENDPOINT) {
va009039 0:98f918e1d528 212 if (desc->bmAttributes == 2) { // bulk
va009039 0:98f918e1d528 213 BulkEp* pEp = new BulkEp(ctlEp->GetAddr(), desc->bEndpointAddress, desc->wMaxPacketSize);
va009039 0:98f918e1d528 214 if (desc->bEndpointAddress & 0x80) {
va009039 0:98f918e1d528 215 m_pEpBulkIn = pEp;
va009039 0:98f918e1d528 216 } else {
va009039 0:98f918e1d528 217 m_pEpBulkOut = pEp;
va009039 0:98f918e1d528 218 }
va009039 0:98f918e1d528 219 }
va009039 0:98f918e1d528 220 }
va009039 0:98f918e1d528 221 }
va009039 0:98f918e1d528 222 delete[] buf;
va009039 0:98f918e1d528 223 if (m_pEpBulkIn && m_pEpBulkOut) {
va009039 0:98f918e1d528 224 return USB_OK;
va009039 0:98f918e1d528 225 }
va009039 0:98f918e1d528 226 return USB_ERROR;
va009039 0:98f918e1d528 227 }
va009039 0:98f918e1d528 228
va009039 0:98f918e1d528 229 int UsbFlashDrive::BulkOnlyMassStorageReset(ControlEp* ctlEp)
va009039 0:98f918e1d528 230 {
va009039 0:98f918e1d528 231 TEST_ASSERT(ctlEp);
va009039 0:98f918e1d528 232 int rc = ctlEp->controlReceive(0x21, 0xff, 0x0000, m_interface, NULL, 0);
va009039 0:98f918e1d528 233 TEST_ASSERT(rc == USB_OK);
va009039 0:98f918e1d528 234 return rc;
va009039 0:98f918e1d528 235 }
va009039 0:98f918e1d528 236
va009039 0:98f918e1d528 237 int UsbFlashDrive::GetMaxLUN(ControlEp* ctlEp)
va009039 0:98f918e1d528 238 {
va009039 0:98f918e1d528 239 TEST_ASSERT(ctlEp);
va009039 0:98f918e1d528 240 TEST_ASSERT(m_interface == 0);
va009039 0:98f918e1d528 241 uint8_t temp[1];
va009039 0:98f918e1d528 242 int rc = ctlEp->controlReceive(0xa1, 0xfe, 0x0000, m_interface, temp, sizeof(temp));
va009039 0:98f918e1d528 243 TEST_ASSERT(rc == USB_OK);
va009039 0:98f918e1d528 244 DBG_BYTES("GetMaxLUN", temp, sizeof(temp));
va009039 0:98f918e1d528 245 m_MaxLUN = temp[0];
va009039 0:98f918e1d528 246 TEST_ASSERT(m_MaxLUN <= 15);
va009039 0:98f918e1d528 247 return rc;
va009039 0:98f918e1d528 248 }
va009039 0:98f918e1d528 249
va009039 0:98f918e1d528 250
va009039 0:98f918e1d528 251 int UsbFlashDrive::TestUnitReady()
va009039 0:98f918e1d528 252 {
va009039 0:98f918e1d528 253 const uint8_t cdb[6] = {SCSI_CMD_TEST_UNIT_READY, 0x00, 0x00, 0x00, 0x00, 0x00};
va009039 0:98f918e1d528 254 m_CBW.dCBWDataTraansferLength = 0;
va009039 0:98f918e1d528 255 m_CBW.bmCBWFlags = 0x00;
va009039 0:98f918e1d528 256 CommandTransport(cdb, sizeof(cdb));
va009039 0:98f918e1d528 257 StatusTransport();
va009039 0:98f918e1d528 258 return 0;
va009039 0:98f918e1d528 259 }
va009039 0:98f918e1d528 260
va009039 0:98f918e1d528 261 int UsbFlashDrive::GetSenseInfo()
va009039 0:98f918e1d528 262 {
va009039 0:98f918e1d528 263 const uint8_t cdb[6] = {SCSI_CMD_REQUEST_SENSE, 0x00, 0x00, 0x00, 18, 0x00};
va009039 0:98f918e1d528 264 m_CBW.dCBWDataTraansferLength = 18;
va009039 0:98f918e1d528 265 m_CBW.bmCBWFlags = 0x80; // data In
va009039 0:98f918e1d528 266 CommandTransport(cdb, sizeof(cdb));
va009039 0:98f918e1d528 267
va009039 0:98f918e1d528 268 uint8_t buf[18];
va009039 0:98f918e1d528 269 _bulkRecv(buf, sizeof(buf));
va009039 0:98f918e1d528 270 DBG_HEX(buf, sizeof(buf));
va009039 0:98f918e1d528 271
va009039 0:98f918e1d528 272 StatusTransport();
va009039 0:98f918e1d528 273 TEST_ASSERT(m_CSW.bCSWStatus == 0x00);
va009039 0:98f918e1d528 274 return 0;
va009039 0:98f918e1d528 275 }
va009039 0:98f918e1d528 276
va009039 0:98f918e1d528 277 int UsbFlashDrive::ReadCapacity()
va009039 0:98f918e1d528 278 {
va009039 0:98f918e1d528 279 const uint8_t cdb[10] = {SCSI_CMD_READ_CAPACITY, 0x00, 0x00, 0x00, 0x00,
va009039 0:98f918e1d528 280 0x00, 0x00, 0x00, 0x00, 0x00};
va009039 0:98f918e1d528 281 m_CBW.dCBWDataTraansferLength = 8;
va009039 0:98f918e1d528 282 m_CBW.bmCBWFlags = 0x80; // data In
va009039 0:98f918e1d528 283 CommandTransport(cdb, sizeof(cdb));
va009039 0:98f918e1d528 284
va009039 0:98f918e1d528 285 uint8_t buf[8];
va009039 0:98f918e1d528 286 int rc = _bulkRecv(buf, sizeof(buf));
va009039 0:98f918e1d528 287 TEST_ASSERT(rc >= 0);
va009039 0:98f918e1d528 288 DBG_HEX(buf, sizeof(buf));
va009039 0:98f918e1d528 289
va009039 0:98f918e1d528 290 StatusTransport();
va009039 0:98f918e1d528 291 TEST_ASSERT(m_CSW.bCSWStatus == 0x00);
va009039 0:98f918e1d528 292
va009039 0:98f918e1d528 293 m_numBlocks = BE32(buf);
va009039 0:98f918e1d528 294 m_BlockSize = BE32(buf+4);
va009039 0:98f918e1d528 295 DBG("m_numBlocks=%d m_BlockSize=%d\n", m_numBlocks, m_BlockSize);
va009039 0:98f918e1d528 296 TEST_ASSERT(m_BlockSize == 512);
va009039 0:98f918e1d528 297 TEST_ASSERT(m_numBlocks > 0);
va009039 0:98f918e1d528 298 return 0;
va009039 0:98f918e1d528 299 }
va009039 0:98f918e1d528 300
va009039 0:98f918e1d528 301 int UsbFlashDrive::Inquire()
va009039 0:98f918e1d528 302 {
va009039 0:98f918e1d528 303 const uint8_t cdb[6] = {SCSI_CMD_INQUIRY, 0x00, 0x00, 0x00, 36, 0x00};
va009039 0:98f918e1d528 304 m_CBW.dCBWDataTraansferLength = 36;
va009039 0:98f918e1d528 305 m_CBW.bmCBWFlags = 0x80; // data In
va009039 0:98f918e1d528 306 CommandTransport(cdb, sizeof(cdb));
va009039 0:98f918e1d528 307
va009039 0:98f918e1d528 308 uint8_t buf[36];
va009039 0:98f918e1d528 309 int rc = _bulkRecv(buf, sizeof(buf));
va009039 0:98f918e1d528 310 TEST_ASSERT(rc >= 0);
va009039 0:98f918e1d528 311 DBG_HEX(buf, sizeof(buf));
va009039 0:98f918e1d528 312
va009039 0:98f918e1d528 313 StatusTransport();
va009039 0:98f918e1d528 314 return 0;
va009039 0:98f918e1d528 315 }
va009039 0:98f918e1d528 316
va009039 0:98f918e1d528 317 int UsbFlashDrive::MS_BulkRecv(uint32_t block_number, int num_blocks, uint8_t* user_buffer)
va009039 0:98f918e1d528 318 {
va009039 0:98f918e1d528 319 TEST_ASSERT(m_BlockSize == 512);
va009039 0:98f918e1d528 320 TEST_ASSERT(num_blocks == 1);
va009039 0:98f918e1d528 321 TEST_ASSERT(user_buffer);
va009039 0:98f918e1d528 322 uint8_t cdb[10] = {SCSI_CMD_READ_10, 0x00, 0x00, 0x00, 0x00,
va009039 0:98f918e1d528 323 0x00, 0x00, 0x00, 0x00, 0x00};
va009039 0:98f918e1d528 324 BE32(block_number, cdb+2);
va009039 0:98f918e1d528 325 BE16(num_blocks, cdb+7);
va009039 0:98f918e1d528 326 uint32_t len = m_BlockSize * num_blocks;
va009039 0:98f918e1d528 327 TEST_ASSERT(len <= 512);
va009039 0:98f918e1d528 328 m_CBW.dCBWDataTraansferLength = len;
va009039 0:98f918e1d528 329 m_CBW.bmCBWFlags = 0x80; // data In
va009039 0:98f918e1d528 330 CommandTransport(cdb, sizeof(cdb));
va009039 0:98f918e1d528 331
va009039 0:98f918e1d528 332 int ret = _bulkRecv(user_buffer, len);
va009039 0:98f918e1d528 333 //DBG_HEX(user_buffer, len);
va009039 0:98f918e1d528 334
va009039 0:98f918e1d528 335 StatusTransport();
va009039 0:98f918e1d528 336 TEST_ASSERT(m_CSW.bCSWStatus == 0x00);
va009039 0:98f918e1d528 337 return ret;
va009039 0:98f918e1d528 338 }
va009039 0:98f918e1d528 339
va009039 0:98f918e1d528 340 int UsbFlashDrive::MS_BulkSend(uint32_t block_number, int num_blocks, const uint8_t* user_buffer)
va009039 0:98f918e1d528 341 {
va009039 0:98f918e1d528 342 #ifdef WRITE_PROTECT
va009039 0:98f918e1d528 343 return 0;
va009039 0:98f918e1d528 344 #else
va009039 0:98f918e1d528 345 TEST_ASSERT(num_blocks == 1);
va009039 0:98f918e1d528 346 TEST_ASSERT(user_buffer);
va009039 0:98f918e1d528 347 uint8_t cdb[10] = {SCSI_CMD_WRITE_10, 0x00, 0x00, 0x00, 0x00,
va009039 0:98f918e1d528 348 0x00, 0x00, 0x00, 0x00, 0x00};
va009039 0:98f918e1d528 349 BE32(block_number, cdb+2);
va009039 0:98f918e1d528 350 BE16(num_blocks, cdb+7);
va009039 0:98f918e1d528 351 uint32_t len = m_BlockSize * num_blocks;
va009039 0:98f918e1d528 352 TEST_ASSERT(len <= 512);
va009039 0:98f918e1d528 353 m_CBW.dCBWDataTraansferLength = len;
va009039 0:98f918e1d528 354 m_CBW.bmCBWFlags = 0x00; // data Out
va009039 0:98f918e1d528 355 CommandTransport(cdb, sizeof(cdb));
va009039 0:98f918e1d528 356
va009039 0:98f918e1d528 357 int ret = _bulkSend(user_buffer, len);
va009039 0:98f918e1d528 358 //DBG_HEX(user_buffer, len);
va009039 0:98f918e1d528 359
va009039 0:98f918e1d528 360 StatusTransport();
va009039 0:98f918e1d528 361 TEST_ASSERT(m_CSW.bCSWStatus == 0x00);
va009039 0:98f918e1d528 362 return ret;
va009039 0:98f918e1d528 363 #endif //WRITE_PROTECT
va009039 0:98f918e1d528 364 }
va009039 0:98f918e1d528 365
va009039 0:98f918e1d528 366 int UsbFlashDrive::CommandTransport(const uint8_t* cdb, int size)
va009039 0:98f918e1d528 367 {
va009039 0:98f918e1d528 368 TEST_ASSERT(cdb);
va009039 0:98f918e1d528 369 TEST_ASSERT(size >= 6);
va009039 0:98f918e1d528 370 TEST_ASSERT(size <= 16);
va009039 0:98f918e1d528 371 m_CBW.bCBWLUN = m_lun;
va009039 0:98f918e1d528 372 m_CBW.bCBWCBLength = size;
va009039 0:98f918e1d528 373 memcpy(m_CBW.CBWCB, cdb, size);
va009039 0:98f918e1d528 374
va009039 0:98f918e1d528 375 m_CBW.dCBWSignature = 0x43425355;
va009039 0:98f918e1d528 376 m_CBW.dCBWTag = m_tag++;
va009039 0:98f918e1d528 377 m_CBW.bCBWLUN = 0;
va009039 0:98f918e1d528 378 //DBG_HEX((uint8_t*)&m_CBW, sizeof(CBW));
va009039 0:98f918e1d528 379 int rc = _bulkSend((uint8_t*)&m_CBW, sizeof(CBW));
va009039 0:98f918e1d528 380 return rc;
va009039 0:98f918e1d528 381 }
va009039 0:98f918e1d528 382
va009039 0:98f918e1d528 383 int UsbFlashDrive::StatusTransport()
va009039 0:98f918e1d528 384 {
va009039 0:98f918e1d528 385 TEST_ASSERT(sizeof(CSW) == 13);
va009039 0:98f918e1d528 386 int rc = _bulkRecv((uint8_t*)&m_CSW, sizeof(CSW));
va009039 0:98f918e1d528 387 //DBG_HEX((uint8_t*)&m_CSW, sizeof(CSW));
va009039 0:98f918e1d528 388 TEST_ASSERT(m_CSW.dCSWSignature == 0x53425355);
va009039 0:98f918e1d528 389 TEST_ASSERT(m_CSW.dCSWTag == m_CBW.dCBWTag);
va009039 0:98f918e1d528 390 TEST_ASSERT(m_CSW.dCSWDataResidue == 0);
va009039 0:98f918e1d528 391 return rc;
va009039 0:98f918e1d528 392 }
va009039 0:98f918e1d528 393
va009039 0:98f918e1d528 394 int UsbFlashDrive::_bulkRecv(uint8_t* buf, int size)
va009039 0:98f918e1d528 395 {
va009039 0:98f918e1d528 396 TEST_ASSERT(m_pEpBulkIn);
va009039 0:98f918e1d528 397 int ret = m_pEpBulkIn->bulkReceive(buf, size);
va009039 0:98f918e1d528 398 return ret;
va009039 0:98f918e1d528 399 }
va009039 0:98f918e1d528 400
va009039 0:98f918e1d528 401 int UsbFlashDrive::_bulkSend(const uint8_t* buf, int size)
va009039 0:98f918e1d528 402 {
va009039 0:98f918e1d528 403 TEST_ASSERT(m_pEpBulkOut);
va009039 0:98f918e1d528 404 int ret = m_pEpBulkOut->bulkSend(buf, size);
va009039 0:98f918e1d528 405 return ret;
va009039 0:98f918e1d528 406 }