Keyboard firmwares for Atmel AVR and Cortex-M
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

USBMSD.cpp 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655
  1. /* Copyright (c) 2010-2011 mbed.org, MIT License
  2. *
  3. * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
  4. * and associated documentation files (the "Software"), to deal in the Software without
  5. * restriction, including without limitation the rights to use, copy, modify, merge, publish,
  6. * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
  7. * Software is furnished to do so, subject to the following conditions:
  8. *
  9. * The above copyright notice and this permission notice shall be included in all copies or
  10. * substantial portions of the Software.
  11. *
  12. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
  13. * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  14. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  15. * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  16. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  17. */
  18. #include "stdint.h"
  19. #include "USBMSD.h"
  20. #define DISK_OK 0x00
  21. #define NO_INIT 0x01
  22. #define NO_DISK 0x02
  23. #define WRITE_PROTECT 0x04
  24. #define CBW_Signature 0x43425355
  25. #define CSW_Signature 0x53425355
  26. // SCSI Commands
  27. #define TEST_UNIT_READY 0x00
  28. #define REQUEST_SENSE 0x03
  29. #define FORMAT_UNIT 0x04
  30. #define INQUIRY 0x12
  31. #define MODE_SELECT6 0x15
  32. #define MODE_SENSE6 0x1A
  33. #define START_STOP_UNIT 0x1B
  34. #define MEDIA_REMOVAL 0x1E
  35. #define READ_FORMAT_CAPACITIES 0x23
  36. #define READ_CAPACITY 0x25
  37. #define READ10 0x28
  38. #define WRITE10 0x2A
  39. #define VERIFY10 0x2F
  40. #define READ12 0xA8
  41. #define WRITE12 0xAA
  42. #define MODE_SELECT10 0x55
  43. #define MODE_SENSE10 0x5A
  44. // MSC class specific requests
  45. #define MSC_REQUEST_RESET 0xFF
  46. #define MSC_REQUEST_GET_MAX_LUN 0xFE
  47. #define DEFAULT_CONFIGURATION (1)
  48. // max packet size
  49. #define MAX_PACKET MAX_PACKET_SIZE_EPBULK
  50. // CSW Status
  51. enum Status {
  52. CSW_PASSED,
  53. CSW_FAILED,
  54. CSW_ERROR,
  55. };
  56. USBMSD::USBMSD(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) {
  57. stage = READ_CBW;
  58. memset((void *)&cbw, 0, sizeof(CBW));
  59. memset((void *)&csw, 0, sizeof(CSW));
  60. page = NULL;
  61. }
  62. USBMSD::~USBMSD() {
  63. disconnect();
  64. }
  65. // Called in ISR context to process a class specific request
  66. bool USBMSD::USBCallback_request(void) {
  67. bool success = false;
  68. CONTROL_TRANSFER * transfer = getTransferPtr();
  69. static uint8_t maxLUN[1] = {0};
  70. if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
  71. switch (transfer->setup.bRequest) {
  72. case MSC_REQUEST_RESET:
  73. reset();
  74. success = true;
  75. break;
  76. case MSC_REQUEST_GET_MAX_LUN:
  77. transfer->remaining = 1;
  78. transfer->ptr = maxLUN;
  79. transfer->direction = DEVICE_TO_HOST;
  80. success = true;
  81. break;
  82. default:
  83. break;
  84. }
  85. }
  86. return success;
  87. }
  88. bool USBMSD::connect(bool blocking) {
  89. //disk initialization
  90. if (disk_status() & NO_INIT) {
  91. if (disk_initialize()) {
  92. return false;
  93. }
  94. }
  95. // get number of blocks
  96. BlockCount = disk_sectors();
  97. // get memory size
  98. MemorySize = disk_size();
  99. if (BlockCount > 0) {
  100. BlockSize = MemorySize / BlockCount;
  101. if (BlockSize != 0) {
  102. free(page);
  103. page = (uint8_t *)malloc(BlockSize * sizeof(uint8_t));
  104. if (page == NULL)
  105. return false;
  106. }
  107. } else {
  108. return false;
  109. }
  110. //connect the device
  111. USBDevice::connect(blocking);
  112. return true;
  113. }
  114. void USBMSD::disconnect() {
  115. USBDevice::disconnect();
  116. //De-allocate MSD page size:
  117. free(page);
  118. page = NULL;
  119. }
  120. void USBMSD::reset() {
  121. stage = READ_CBW;
  122. }
  123. // Called in ISR context called when a data is received
  124. bool USBMSD::EPBULK_OUT_callback() {
  125. uint32_t size = 0;
  126. uint8_t buf[MAX_PACKET_SIZE_EPBULK];
  127. readEP(EPBULK_OUT, buf, &size, MAX_PACKET_SIZE_EPBULK);
  128. switch (stage) {
  129. // the device has to decode the CBW received
  130. case READ_CBW:
  131. CBWDecode(buf, size);
  132. break;
  133. // the device has to receive data from the host
  134. case PROCESS_CBW:
  135. switch (cbw.CB[0]) {
  136. case WRITE10:
  137. case WRITE12:
  138. memoryWrite(buf, size);
  139. break;
  140. case VERIFY10:
  141. memoryVerify(buf, size);
  142. break;
  143. }
  144. break;
  145. // an error has occured: stall endpoint and send CSW
  146. default:
  147. stallEndpoint(EPBULK_OUT);
  148. csw.Status = CSW_ERROR;
  149. sendCSW();
  150. break;
  151. }
  152. //reactivate readings on the OUT bulk endpoint
  153. readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
  154. return true;
  155. }
  156. // Called in ISR context when a data has been transferred
  157. bool USBMSD::EPBULK_IN_callback() {
  158. switch (stage) {
  159. // the device has to send data to the host
  160. case PROCESS_CBW:
  161. switch (cbw.CB[0]) {
  162. case READ10:
  163. case READ12:
  164. memoryRead();
  165. break;
  166. }
  167. break;
  168. //the device has to send a CSW
  169. case SEND_CSW:
  170. sendCSW();
  171. break;
  172. // the host has received the CSW -> we wait a CBW
  173. case WAIT_CSW:
  174. stage = READ_CBW;
  175. break;
  176. // an error has occured
  177. default:
  178. stallEndpoint(EPBULK_IN);
  179. sendCSW();
  180. break;
  181. }
  182. return true;
  183. }
  184. void USBMSD::memoryWrite (uint8_t * buf, uint16_t size) {
  185. if ((addr + size) > MemorySize) {
  186. size = MemorySize - addr;
  187. stage = ERROR;
  188. stallEndpoint(EPBULK_OUT);
  189. }
  190. // we fill an array in RAM of 1 block before writing it in memory
  191. for (int i = 0; i < size; i++)
  192. page[addr%BlockSize + i] = buf[i];
  193. // if the array is filled, write it in memory
  194. if (!((addr + size)%BlockSize)) {
  195. if (!(disk_status() & WRITE_PROTECT)) {
  196. disk_write(page, addr/BlockSize, 1);
  197. }
  198. }
  199. addr += size;
  200. length -= size;
  201. csw.DataResidue -= size;
  202. if ((!length) || (stage != PROCESS_CBW)) {
  203. csw.Status = (stage == ERROR) ? CSW_FAILED : CSW_PASSED;
  204. sendCSW();
  205. }
  206. }
  207. void USBMSD::memoryVerify (uint8_t * buf, uint16_t size) {
  208. uint32_t n;
  209. if ((addr + size) > MemorySize) {
  210. size = MemorySize - addr;
  211. stage = ERROR;
  212. stallEndpoint(EPBULK_OUT);
  213. }
  214. // beginning of a new block -> load a whole block in RAM
  215. if (!(addr%BlockSize))
  216. disk_read(page, addr/BlockSize, 1);
  217. // info are in RAM -> no need to re-read memory
  218. for (n = 0; n < size; n++) {
  219. if (page[addr%BlockSize + n] != buf[n]) {
  220. memOK = false;
  221. break;
  222. }
  223. }
  224. addr += size;
  225. length -= size;
  226. csw.DataResidue -= size;
  227. if ( !length || (stage != PROCESS_CBW)) {
  228. csw.Status = (memOK && (stage == PROCESS_CBW)) ? CSW_PASSED : CSW_FAILED;
  229. sendCSW();
  230. }
  231. }
  232. bool USBMSD::inquiryRequest (void) {
  233. uint8_t inquiry[] = { 0x00, 0x80, 0x00, 0x01,
  234. 36 - 4, 0x80, 0x00, 0x00,
  235. 'M', 'B', 'E', 'D', '.', 'O', 'R', 'G',
  236. 'M', 'B', 'E', 'D', ' ', 'U', 'S', 'B', ' ', 'D', 'I', 'S', 'K', ' ', ' ', ' ',
  237. '1', '.', '0', ' ',
  238. };
  239. if (!write(inquiry, sizeof(inquiry))) {
  240. return false;
  241. }
  242. return true;
  243. }
  244. bool USBMSD::readFormatCapacity() {
  245. uint8_t capacity[] = { 0x00, 0x00, 0x00, 0x08,
  246. (uint8_t)((BlockCount >> 24) & 0xff),
  247. (uint8_t)((BlockCount >> 16) & 0xff),
  248. (uint8_t)((BlockCount >> 8) & 0xff),
  249. (uint8_t)((BlockCount >> 0) & 0xff),
  250. 0x02,
  251. (uint8_t)((BlockSize >> 16) & 0xff),
  252. (uint8_t)((BlockSize >> 8) & 0xff),
  253. (uint8_t)((BlockSize >> 0) & 0xff),
  254. };
  255. if (!write(capacity, sizeof(capacity))) {
  256. return false;
  257. }
  258. return true;
  259. }
  260. bool USBMSD::readCapacity (void) {
  261. uint8_t capacity[] = {
  262. (uint8_t)(((BlockCount - 1) >> 24) & 0xff),
  263. (uint8_t)(((BlockCount - 1) >> 16) & 0xff),
  264. (uint8_t)(((BlockCount - 1) >> 8) & 0xff),
  265. (uint8_t)(((BlockCount - 1) >> 0) & 0xff),
  266. (uint8_t)((BlockSize >> 24) & 0xff),
  267. (uint8_t)((BlockSize >> 16) & 0xff),
  268. (uint8_t)((BlockSize >> 8) & 0xff),
  269. (uint8_t)((BlockSize >> 0) & 0xff),
  270. };
  271. if (!write(capacity, sizeof(capacity))) {
  272. return false;
  273. }
  274. return true;
  275. }
  276. bool USBMSD::write (uint8_t * buf, uint16_t size) {
  277. if (size >= cbw.DataLength) {
  278. size = cbw.DataLength;
  279. }
  280. stage = SEND_CSW;
  281. if (!writeNB(EPBULK_IN, buf, size, MAX_PACKET_SIZE_EPBULK)) {
  282. return false;
  283. }
  284. csw.DataResidue -= size;
  285. csw.Status = CSW_PASSED;
  286. return true;
  287. }
  288. bool USBMSD::modeSense6 (void) {
  289. uint8_t sense6[] = { 0x03, 0x00, 0x00, 0x00 };
  290. if (!write(sense6, sizeof(sense6))) {
  291. return false;
  292. }
  293. return true;
  294. }
  295. void USBMSD::sendCSW() {
  296. csw.Signature = CSW_Signature;
  297. writeNB(EPBULK_IN, (uint8_t *)&csw, sizeof(CSW), MAX_PACKET_SIZE_EPBULK);
  298. stage = WAIT_CSW;
  299. }
  300. bool USBMSD::requestSense (void) {
  301. uint8_t request_sense[] = {
  302. 0x70,
  303. 0x00,
  304. 0x05, // Sense Key: illegal request
  305. 0x00,
  306. 0x00,
  307. 0x00,
  308. 0x00,
  309. 0x0A,
  310. 0x00,
  311. 0x00,
  312. 0x00,
  313. 0x00,
  314. 0x30,
  315. 0x01,
  316. 0x00,
  317. 0x00,
  318. 0x00,
  319. 0x00,
  320. };
  321. if (!write(request_sense, sizeof(request_sense))) {
  322. return false;
  323. }
  324. return true;
  325. }
  326. void USBMSD::fail() {
  327. csw.Status = CSW_FAILED;
  328. sendCSW();
  329. }
  330. void USBMSD::CBWDecode(uint8_t * buf, uint16_t size) {
  331. if (size == sizeof(cbw)) {
  332. memcpy((uint8_t *)&cbw, buf, size);
  333. if (cbw.Signature == CBW_Signature) {
  334. csw.Tag = cbw.Tag;
  335. csw.DataResidue = cbw.DataLength;
  336. if ((cbw.CBLength < 1) || (cbw.CBLength > 16) ) {
  337. fail();
  338. } else {
  339. switch (cbw.CB[0]) {
  340. case TEST_UNIT_READY:
  341. testUnitReady();
  342. break;
  343. case REQUEST_SENSE:
  344. requestSense();
  345. break;
  346. case INQUIRY:
  347. inquiryRequest();
  348. break;
  349. case MODE_SENSE6:
  350. modeSense6();
  351. break;
  352. case READ_FORMAT_CAPACITIES:
  353. readFormatCapacity();
  354. break;
  355. case READ_CAPACITY:
  356. readCapacity();
  357. break;
  358. case READ10:
  359. case READ12:
  360. if (infoTransfer()) {
  361. if ((cbw.Flags & 0x80)) {
  362. stage = PROCESS_CBW;
  363. memoryRead();
  364. } else {
  365. stallEndpoint(EPBULK_OUT);
  366. csw.Status = CSW_ERROR;
  367. sendCSW();
  368. }
  369. }
  370. break;
  371. case WRITE10:
  372. case WRITE12:
  373. if (infoTransfer()) {
  374. if (!(cbw.Flags & 0x80)) {
  375. stage = PROCESS_CBW;
  376. } else {
  377. stallEndpoint(EPBULK_IN);
  378. csw.Status = CSW_ERROR;
  379. sendCSW();
  380. }
  381. }
  382. break;
  383. case VERIFY10:
  384. if (!(cbw.CB[1] & 0x02)) {
  385. csw.Status = CSW_PASSED;
  386. sendCSW();
  387. break;
  388. }
  389. if (infoTransfer()) {
  390. if (!(cbw.Flags & 0x80)) {
  391. stage = PROCESS_CBW;
  392. memOK = true;
  393. } else {
  394. stallEndpoint(EPBULK_IN);
  395. csw.Status = CSW_ERROR;
  396. sendCSW();
  397. }
  398. }
  399. break;
  400. case MEDIA_REMOVAL:
  401. csw.Status = CSW_PASSED;
  402. sendCSW();
  403. break;
  404. default:
  405. fail();
  406. break;
  407. }
  408. }
  409. }
  410. }
  411. }
  412. void USBMSD::testUnitReady (void) {
  413. if (cbw.DataLength != 0) {
  414. if ((cbw.Flags & 0x80) != 0) {
  415. stallEndpoint(EPBULK_IN);
  416. } else {
  417. stallEndpoint(EPBULK_OUT);
  418. }
  419. }
  420. csw.Status = CSW_PASSED;
  421. sendCSW();
  422. }
  423. void USBMSD::memoryRead (void) {
  424. uint32_t n;
  425. n = (length > MAX_PACKET) ? MAX_PACKET : length;
  426. if ((addr + n) > MemorySize) {
  427. n = MemorySize - addr;
  428. stage = ERROR;
  429. }
  430. // we read an entire block
  431. if (!(addr%BlockSize))
  432. disk_read(page, addr/BlockSize, 1);
  433. // write data which are in RAM
  434. writeNB(EPBULK_IN, &page[addr%BlockSize], n, MAX_PACKET_SIZE_EPBULK);
  435. addr += n;
  436. length -= n;
  437. csw.DataResidue -= n;
  438. if ( !length || (stage != PROCESS_CBW)) {
  439. csw.Status = (stage == PROCESS_CBW) ? CSW_PASSED : CSW_FAILED;
  440. stage = (stage == PROCESS_CBW) ? SEND_CSW : stage;
  441. }
  442. }
  443. bool USBMSD::infoTransfer (void) {
  444. uint32_t n;
  445. // Logical Block Address of First Block
  446. n = (cbw.CB[2] << 24) | (cbw.CB[3] << 16) | (cbw.CB[4] << 8) | (cbw.CB[5] << 0);
  447. addr = n * BlockSize;
  448. // Number of Blocks to transfer
  449. switch (cbw.CB[0]) {
  450. case READ10:
  451. case WRITE10:
  452. case VERIFY10:
  453. n = (cbw.CB[7] << 8) | (cbw.CB[8] << 0);
  454. break;
  455. case READ12:
  456. case WRITE12:
  457. n = (cbw.CB[6] << 24) | (cbw.CB[7] << 16) | (cbw.CB[8] << 8) | (cbw.CB[9] << 0);
  458. break;
  459. }
  460. length = n * BlockSize;
  461. if (!cbw.DataLength) { // host requests no data
  462. csw.Status = CSW_FAILED;
  463. sendCSW();
  464. return false;
  465. }
  466. if (cbw.DataLength != length) {
  467. if ((cbw.Flags & 0x80) != 0) {
  468. stallEndpoint(EPBULK_IN);
  469. } else {
  470. stallEndpoint(EPBULK_OUT);
  471. }
  472. csw.Status = CSW_FAILED;
  473. sendCSW();
  474. return false;
  475. }
  476. return true;
  477. }
  478. // Called in ISR context
  479. // Set configuration. Return false if the
  480. // configuration is not supported.
  481. bool USBMSD::USBCallback_setConfiguration(uint8_t configuration) {
  482. if (configuration != DEFAULT_CONFIGURATION) {
  483. return false;
  484. }
  485. // Configure endpoints > 0
  486. addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
  487. addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
  488. //activate readings
  489. readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
  490. return true;
  491. }
  492. uint8_t * USBMSD::stringIinterfaceDesc() {
  493. static uint8_t stringIinterfaceDescriptor[] = {
  494. 0x08, //bLength
  495. STRING_DESCRIPTOR, //bDescriptorType 0x03
  496. 'M',0,'S',0,'D',0 //bString iInterface - MSD
  497. };
  498. return stringIinterfaceDescriptor;
  499. }
  500. uint8_t * USBMSD::stringIproductDesc() {
  501. static uint8_t stringIproductDescriptor[] = {
  502. 0x12, //bLength
  503. STRING_DESCRIPTOR, //bDescriptorType 0x03
  504. 'M',0,'b',0,'e',0,'d',0,' ',0,'M',0,'S',0,'D',0 //bString iProduct - Mbed Audio
  505. };
  506. return stringIproductDescriptor;
  507. }
  508. uint8_t * USBMSD::configurationDesc() {
  509. static uint8_t configDescriptor[] = {
  510. // Configuration 1
  511. 9, // bLength
  512. 2, // bDescriptorType
  513. LSB(9 + 9 + 7 + 7), // wTotalLength
  514. MSB(9 + 9 + 7 + 7),
  515. 0x01, // bNumInterfaces
  516. 0x01, // bConfigurationValue: 0x01 is used to select this configuration
  517. 0x00, // iConfiguration: no string to describe this configuration
  518. 0xC0, // bmAttributes
  519. 100, // bMaxPower, device power consumption is 100 mA
  520. // Interface 0, Alternate Setting 0, MSC Class
  521. 9, // bLength
  522. 4, // bDescriptorType
  523. 0x00, // bInterfaceNumber
  524. 0x00, // bAlternateSetting
  525. 0x02, // bNumEndpoints
  526. 0x08, // bInterfaceClass
  527. 0x06, // bInterfaceSubClass
  528. 0x50, // bInterfaceProtocol
  529. 0x04, // iInterface
  530. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  531. 7, // bLength
  532. 5, // bDescriptorType
  533. PHY_TO_DESC(EPBULK_IN), // bEndpointAddress
  534. 0x02, // bmAttributes (0x02=bulk)
  535. LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
  536. MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
  537. 0, // bInterval
  538. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  539. 7, // bLength
  540. 5, // bDescriptorType
  541. PHY_TO_DESC(EPBULK_OUT), // bEndpointAddress
  542. 0x02, // bmAttributes (0x02=bulk)
  543. LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
  544. MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
  545. 0 // bInterval
  546. };
  547. return configDescriptor;
  548. }