|
38 | 38 | #include "settings.h" |
39 | 39 | #include "target_family.h" |
40 | 40 | #include "flash_manager.h" |
| 41 | +#include "util.h" |
41 | 42 | #include <string.h> |
42 | 43 | #include "daplink_vendor_commands.h" |
43 | 44 |
|
44 | 45 | #ifdef DRAG_N_DROP_SUPPORT |
45 | 46 | #include "file_stream.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 | //************************************************************************************************** |
@@ -150,20 +158,49 @@ uint32_t DAP_ProcessVendorCommand(const uint8_t *request, uint8_t *response) { |
150 | 158 | // open mass storage device stream |
151 | 159 | *response = stream_open((stream_type_t)(*request)); |
152 | 160 | num += (1 << 16) | 1; |
| 161 | + file_stream_buffer_pos = 0; |
153 | 162 | break; |
154 | 163 | } |
155 | 164 | case ID_DAP_MSD_Close: { |
| 165 | + // write the remaining data in the buffer |
| 166 | + if (file_stream_buffer_pos) { |
| 167 | + *response = stream_write(file_stream_buffer, file_stream_buffer_pos); |
| 168 | + file_stream_buffer_pos = 0; |
| 169 | + if (ERROR_SUCCESS != *response && |
| 170 | + ERROR_SUCCESS_DONE != *response && |
| 171 | + ERROR_SUCCESS_DONE_OR_CONTINUE != *response) { |
| 172 | + num += 1; |
| 173 | + break; |
| 174 | + } |
| 175 | + } |
156 | 176 | // close mass storage device stream |
157 | 177 | *response = stream_close(); |
158 | 178 | num += 1; |
159 | 179 | break; |
160 | 180 | } |
161 | 181 | case ID_DAP_MSD_Write: { |
162 | | - // write to mass storage device |
| 182 | + // write to mass storage device in blocks of length == vfs sector size |
163 | 183 | uint32_t write_len = *request; |
164 | 184 | request++; |
165 | 185 | main_blink_msc_led(MAIN_LED_FLASH); |
166 | | - *response = stream_write((uint8_t *)request, write_len); |
| 186 | + if (file_stream_buffer_pos || (write_len % VFS_SECTOR_SIZE)) { |
| 187 | + uint32_t write_len_left = write_len; |
| 188 | + while (write_len_left > 0) { |
| 189 | + uint16_t copy_len = MIN(VFS_SECTOR_SIZE - file_stream_buffer_pos, write_len_left); |
| 190 | + memcpy(file_stream_buffer + file_stream_buffer_pos, request, copy_len); |
| 191 | + file_stream_buffer_pos += copy_len; |
| 192 | + write_len_left -= copy_len; |
| 193 | + request += copy_len; |
| 194 | + if (file_stream_buffer_pos >= VFS_SECTOR_SIZE) { |
| 195 | + *response = stream_write(file_stream_buffer, VFS_SECTOR_SIZE); |
| 196 | + file_stream_buffer_pos = 0; |
| 197 | + } else { |
| 198 | + *response = ERROR_SUCCESS; |
| 199 | + } |
| 200 | + } |
| 201 | + } else { |
| 202 | + *response = stream_write((uint8_t *)request, write_len); |
| 203 | + } |
167 | 204 | num += ((write_len + 1) << 16) | 1; |
168 | 205 | break; |
169 | 206 | } |
|
0 commit comments