|
43 | 43 | #if defined(DRAG_N_DROP_SUPPORT) && !defined(DRAG_N_DROP_DISABLE)
|
44 | 44 | #include "file_stream.h"
|
45 | 45 | #include "flash_manager.h"
|
| 46 | +#include "util.h" |
| 47 | + |
| 48 | +// Reusing the MSC sector buffer from vfs_manager.c to save memory |
| 49 | +// as using both at the same time will break anyway |
| 50 | +extern uint32_t usb_buffer[VFS_SECTOR_SIZE / sizeof(uint32_t)]; |
| 51 | +static uint8_t *file_stream_buffer = (uint8_t *)usb_buffer; |
| 52 | +static const uint32_t file_stream_buffer_size = sizeof(usb_buffer); |
| 53 | +static uint16_t file_stream_buffer_pos = 0; |
46 | 54 | #endif
|
47 | 55 |
|
48 | 56 | //**************************************************************************************************
|
@@ -152,20 +160,49 @@ uint32_t DAP_ProcessVendorCommand(const uint8_t *request, uint8_t *response) {
|
152 | 160 | // open mass storage device stream
|
153 | 161 | *response = stream_open((stream_type_t)(*request));
|
154 | 162 | num += (1 << 16) | 1;
|
| 163 | + file_stream_buffer_pos = 0; |
155 | 164 | break;
|
156 | 165 | }
|
157 | 166 | case ID_DAP_MSD_Close: {
|
| 167 | + // write the remaining data in the buffer |
| 168 | + if (file_stream_buffer_pos) { |
| 169 | + *response = stream_write(file_stream_buffer, file_stream_buffer_pos); |
| 170 | + file_stream_buffer_pos = 0; |
| 171 | + if (ERROR_SUCCESS != *response && |
| 172 | + ERROR_SUCCESS_DONE != *response && |
| 173 | + ERROR_SUCCESS_DONE_OR_CONTINUE != *response) { |
| 174 | + num += 1; |
| 175 | + break; |
| 176 | + } |
| 177 | + } |
158 | 178 | // close mass storage device stream
|
159 | 179 | *response = stream_close();
|
160 | 180 | num += 1;
|
161 | 181 | break;
|
162 | 182 | }
|
163 | 183 | case ID_DAP_MSD_Write: {
|
164 |
| - // write to mass storage device |
| 184 | + // write to mass storage device in blocks of length == vfs sector size |
165 | 185 | uint32_t write_len = *request;
|
166 | 186 | request++;
|
167 | 187 | main_blink_msc_led(MAIN_LED_FLASH);
|
168 |
| - *response = stream_write((uint8_t *)request, write_len); |
| 188 | + if (file_stream_buffer_pos || (write_len % VFS_SECTOR_SIZE)) { |
| 189 | + uint32_t write_len_left = write_len; |
| 190 | + while (write_len_left > 0) { |
| 191 | + uint16_t copy_len = MIN(VFS_SECTOR_SIZE - file_stream_buffer_pos, write_len_left); |
| 192 | + memcpy(file_stream_buffer + file_stream_buffer_pos, request, copy_len); |
| 193 | + file_stream_buffer_pos += copy_len; |
| 194 | + write_len_left -= copy_len; |
| 195 | + request += copy_len; |
| 196 | + if (file_stream_buffer_pos >= VFS_SECTOR_SIZE) { |
| 197 | + *response = stream_write(file_stream_buffer, VFS_SECTOR_SIZE); |
| 198 | + file_stream_buffer_pos = 0; |
| 199 | + } else { |
| 200 | + *response = ERROR_SUCCESS; |
| 201 | + } |
| 202 | + } |
| 203 | + } else { |
| 204 | + *response = stream_write((uint8_t *)request, write_len); |
| 205 | + } |
169 | 206 | num += ((write_len + 1) << 16) | 1;
|
170 | 207 | break;
|
171 | 208 | }
|
|
0 commit comments