max32630fthr quad spi , unexpected spi behavior

Committer:
boonshen
Date:
Tue Mar 13 21:12:00 2018 +0000
Revision:
0:a35c40f49345
MAX32630FTHR QuadSPI test

Who changed what in which revision?

UserRevisionLine numberNew contents of line
boonshen 0:a35c40f49345 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
boonshen 0:a35c40f49345 2 *
boonshen 0:a35c40f49345 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
boonshen 0:a35c40f49345 4 * and associated documentation files (the "Software"), to deal in the Software without
boonshen 0:a35c40f49345 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
boonshen 0:a35c40f49345 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
boonshen 0:a35c40f49345 7 * Software is furnished to do so, subject to the following conditions:
boonshen 0:a35c40f49345 8 *
boonshen 0:a35c40f49345 9 * The above copyright notice and this permission notice shall be included in all copies or
boonshen 0:a35c40f49345 10 * substantial portions of the Software.
boonshen 0:a35c40f49345 11 *
boonshen 0:a35c40f49345 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
boonshen 0:a35c40f49345 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
boonshen 0:a35c40f49345 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
boonshen 0:a35c40f49345 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
boonshen 0:a35c40f49345 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
boonshen 0:a35c40f49345 17 */
boonshen 0:a35c40f49345 18
boonshen 0:a35c40f49345 19
boonshen 0:a35c40f49345 20 #ifndef USBMSD_H
boonshen 0:a35c40f49345 21 #define USBMSD_H
boonshen 0:a35c40f49345 22
boonshen 0:a35c40f49345 23 /* These headers are included for child class. */
boonshen 0:a35c40f49345 24 #include "USBEndpoints.h"
boonshen 0:a35c40f49345 25 #include "USBDescriptor.h"
boonshen 0:a35c40f49345 26 #include "USBDevice_Types.h"
boonshen 0:a35c40f49345 27
boonshen 0:a35c40f49345 28 #include "USBDevice.h"
boonshen 0:a35c40f49345 29
boonshen 0:a35c40f49345 30 /**
boonshen 0:a35c40f49345 31 * USBMSD class: generic class in order to use all kinds of blocks storage chip
boonshen 0:a35c40f49345 32 *
boonshen 0:a35c40f49345 33 * Introduction
boonshen 0:a35c40f49345 34 *
boonshen 0:a35c40f49345 35 * The USBMSD implements the MSD protocol. It permits to access a memory chip (flash, sdcard,...)
boonshen 0:a35c40f49345 36 * from a computer over USB. But this class doesn't work standalone, you need to subclass this class
boonshen 0:a35c40f49345 37 * and define virtual functions which are called in USBMSD.
boonshen 0:a35c40f49345 38 *
boonshen 0:a35c40f49345 39 * How to use this class with your chip ?
boonshen 0:a35c40f49345 40 *
boonshen 0:a35c40f49345 41 * You have to inherit and define some pure virtual functions (mandatory step):
boonshen 0:a35c40f49345 42 * - virtual int disk_read(char * data, int block): function to read a block
boonshen 0:a35c40f49345 43 * - virtual int disk_write(const char * data, int block): function to write a block
boonshen 0:a35c40f49345 44 * - virtual int disk_initialize(): function to initialize the memory
boonshen 0:a35c40f49345 45 * - virtual int disk_sectors(): return the number of blocks
boonshen 0:a35c40f49345 46 * - virtual int disk_size(): return the memory size
boonshen 0:a35c40f49345 47 * - virtual int disk_status(): return the status of the storage chip (0: OK, 1: not initialized, 2: no medium in the drive, 4: write protection)
boonshen 0:a35c40f49345 48 *
boonshen 0:a35c40f49345 49 * All functions names are compatible with the fat filesystem library. So you can imagine using your own class with
boonshen 0:a35c40f49345 50 * USBMSD and the fat filesystem library in the same program. Just be careful because there are two different parts which
boonshen 0:a35c40f49345 51 * will access the sd card. You can do a master/slave system using the disk_status method.
boonshen 0:a35c40f49345 52 *
boonshen 0:a35c40f49345 53 * Once these functions defined, you can call connect() (at the end of the constructor of your class for instance)
boonshen 0:a35c40f49345 54 * of USBMSD to connect your mass storage device. connect() will first call disk_status() to test the status of the disk.
boonshen 0:a35c40f49345 55 * If disk_status() returns 1 (disk not initialized), then disk_initialize() is called. After this step, connect() will collect information
boonshen 0:a35c40f49345 56 * such as the number of blocks and the memory size.
boonshen 0:a35c40f49345 57 */
boonshen 0:a35c40f49345 58 class USBMSD: public USBDevice {
boonshen 0:a35c40f49345 59 public:
boonshen 0:a35c40f49345 60
boonshen 0:a35c40f49345 61 /**
boonshen 0:a35c40f49345 62 * Constructor
boonshen 0:a35c40f49345 63 *
boonshen 0:a35c40f49345 64 * @param vendor_id Your vendor_id
boonshen 0:a35c40f49345 65 * @param product_id Your product_id
boonshen 0:a35c40f49345 66 * @param product_release Your preoduct_release
boonshen 0:a35c40f49345 67 */
boonshen 0:a35c40f49345 68 USBMSD(uint16_t vendor_id = 0x0703, uint16_t product_id = 0x0104, uint16_t product_release = 0x0001);
boonshen 0:a35c40f49345 69
boonshen 0:a35c40f49345 70 /**
boonshen 0:a35c40f49345 71 * Connect the USB MSD device. Establish disk initialization before really connect the device.
boonshen 0:a35c40f49345 72 *
boonshen 0:a35c40f49345 73 * @param blocking if not configured
boonshen 0:a35c40f49345 74 * @returns true if successful
boonshen 0:a35c40f49345 75 */
boonshen 0:a35c40f49345 76 bool connect(bool blocking = true);
boonshen 0:a35c40f49345 77
boonshen 0:a35c40f49345 78 /**
boonshen 0:a35c40f49345 79 * Disconnect the USB MSD device.
boonshen 0:a35c40f49345 80 */
boonshen 0:a35c40f49345 81 void disconnect();
boonshen 0:a35c40f49345 82
boonshen 0:a35c40f49345 83 /**
boonshen 0:a35c40f49345 84 * Destructor
boonshen 0:a35c40f49345 85 */
boonshen 0:a35c40f49345 86 ~USBMSD();
boonshen 0:a35c40f49345 87
boonshen 0:a35c40f49345 88 protected:
boonshen 0:a35c40f49345 89
boonshen 0:a35c40f49345 90 /*
boonshen 0:a35c40f49345 91 * read one or more blocks on a storage chip
boonshen 0:a35c40f49345 92 *
boonshen 0:a35c40f49345 93 * @param data pointer where will be stored read data
boonshen 0:a35c40f49345 94 * @param block starting block number
boonshen 0:a35c40f49345 95 * @param count number of blocks to read
boonshen 0:a35c40f49345 96 * @returns 0 if successful
boonshen 0:a35c40f49345 97 */
boonshen 0:a35c40f49345 98 virtual int disk_read(uint8_t* data, uint64_t block, uint8_t count) = 0;
boonshen 0:a35c40f49345 99
boonshen 0:a35c40f49345 100 /*
boonshen 0:a35c40f49345 101 * write one or more blocks on a storage chip
boonshen 0:a35c40f49345 102 *
boonshen 0:a35c40f49345 103 * @param data data to write
boonshen 0:a35c40f49345 104 * @param block starting block number
boonshen 0:a35c40f49345 105 * @param count number of blocks to write
boonshen 0:a35c40f49345 106 * @returns 0 if successful
boonshen 0:a35c40f49345 107 */
boonshen 0:a35c40f49345 108 virtual int disk_write(const uint8_t* data, uint64_t block, uint8_t count) = 0;
boonshen 0:a35c40f49345 109
boonshen 0:a35c40f49345 110 /*
boonshen 0:a35c40f49345 111 * Disk initilization
boonshen 0:a35c40f49345 112 */
boonshen 0:a35c40f49345 113 virtual int disk_initialize() = 0;
boonshen 0:a35c40f49345 114
boonshen 0:a35c40f49345 115 /*
boonshen 0:a35c40f49345 116 * Return the number of blocks
boonshen 0:a35c40f49345 117 *
boonshen 0:a35c40f49345 118 * @returns number of blocks
boonshen 0:a35c40f49345 119 */
boonshen 0:a35c40f49345 120 virtual uint64_t disk_sectors() = 0;
boonshen 0:a35c40f49345 121
boonshen 0:a35c40f49345 122 /*
boonshen 0:a35c40f49345 123 * Return memory size
boonshen 0:a35c40f49345 124 *
boonshen 0:a35c40f49345 125 * @returns memory size
boonshen 0:a35c40f49345 126 */
boonshen 0:a35c40f49345 127 virtual uint64_t disk_size() = 0;
boonshen 0:a35c40f49345 128
boonshen 0:a35c40f49345 129
boonshen 0:a35c40f49345 130 /*
boonshen 0:a35c40f49345 131 * To check the status of the storage chip
boonshen 0:a35c40f49345 132 *
boonshen 0:a35c40f49345 133 * @returns status: 0: OK, 1: disk not initialized, 2: no medium in the drive, 4: write protected
boonshen 0:a35c40f49345 134 */
boonshen 0:a35c40f49345 135 virtual int disk_status() = 0;
boonshen 0:a35c40f49345 136
boonshen 0:a35c40f49345 137 /*
boonshen 0:a35c40f49345 138 * Get string product descriptor
boonshen 0:a35c40f49345 139 *
boonshen 0:a35c40f49345 140 * @returns pointer to the string product descriptor
boonshen 0:a35c40f49345 141 */
boonshen 0:a35c40f49345 142 virtual uint8_t * stringIproductDesc();
boonshen 0:a35c40f49345 143
boonshen 0:a35c40f49345 144 /*
boonshen 0:a35c40f49345 145 * Get string interface descriptor
boonshen 0:a35c40f49345 146 *
boonshen 0:a35c40f49345 147 * @returns pointer to the string interface descriptor
boonshen 0:a35c40f49345 148 */
boonshen 0:a35c40f49345 149 virtual uint8_t * stringIinterfaceDesc();
boonshen 0:a35c40f49345 150
boonshen 0:a35c40f49345 151 /*
boonshen 0:a35c40f49345 152 * Get configuration descriptor
boonshen 0:a35c40f49345 153 *
boonshen 0:a35c40f49345 154 * @returns pointer to the configuration descriptor
boonshen 0:a35c40f49345 155 */
boonshen 0:a35c40f49345 156 virtual uint8_t * configurationDesc();
boonshen 0:a35c40f49345 157
boonshen 0:a35c40f49345 158 /*
boonshen 0:a35c40f49345 159 * Callback called when a packet is received
boonshen 0:a35c40f49345 160 */
boonshen 0:a35c40f49345 161 virtual bool EPBULK_OUT_callback();
boonshen 0:a35c40f49345 162
boonshen 0:a35c40f49345 163 /*
boonshen 0:a35c40f49345 164 * Callback called when a packet has been sent
boonshen 0:a35c40f49345 165 */
boonshen 0:a35c40f49345 166 virtual bool EPBULK_IN_callback();
boonshen 0:a35c40f49345 167
boonshen 0:a35c40f49345 168 /*
boonshen 0:a35c40f49345 169 * Set configuration of device. Add endpoints
boonshen 0:a35c40f49345 170 */
boonshen 0:a35c40f49345 171 virtual bool USBCallback_setConfiguration(uint8_t configuration);
boonshen 0:a35c40f49345 172
boonshen 0:a35c40f49345 173 /*
boonshen 0:a35c40f49345 174 * Callback called to process class specific requests
boonshen 0:a35c40f49345 175 */
boonshen 0:a35c40f49345 176 virtual bool USBCallback_request();
boonshen 0:a35c40f49345 177
boonshen 0:a35c40f49345 178
boonshen 0:a35c40f49345 179 private:
boonshen 0:a35c40f49345 180
boonshen 0:a35c40f49345 181 // MSC Bulk-only Stage
boonshen 0:a35c40f49345 182 enum Stage {
boonshen 0:a35c40f49345 183 READ_CBW, // wait a CBW
boonshen 0:a35c40f49345 184 ERROR, // error
boonshen 0:a35c40f49345 185 PROCESS_CBW, // process a CBW request
boonshen 0:a35c40f49345 186 SEND_CSW, // send a CSW
boonshen 0:a35c40f49345 187 WAIT_CSW, // wait that a CSW has been effectively sent
boonshen 0:a35c40f49345 188 };
boonshen 0:a35c40f49345 189
boonshen 0:a35c40f49345 190 // Bulk-only CBW
boonshen 0:a35c40f49345 191 typedef struct {
boonshen 0:a35c40f49345 192 uint32_t Signature;
boonshen 0:a35c40f49345 193 uint32_t Tag;
boonshen 0:a35c40f49345 194 uint32_t DataLength;
boonshen 0:a35c40f49345 195 uint8_t Flags;
boonshen 0:a35c40f49345 196 uint8_t LUN;
boonshen 0:a35c40f49345 197 uint8_t CBLength;
boonshen 0:a35c40f49345 198 uint8_t CB[16];
boonshen 0:a35c40f49345 199 } PACKED CBW;
boonshen 0:a35c40f49345 200
boonshen 0:a35c40f49345 201 // Bulk-only CSW
boonshen 0:a35c40f49345 202 typedef struct {
boonshen 0:a35c40f49345 203 uint32_t Signature;
boonshen 0:a35c40f49345 204 uint32_t Tag;
boonshen 0:a35c40f49345 205 uint32_t DataResidue;
boonshen 0:a35c40f49345 206 uint8_t Status;
boonshen 0:a35c40f49345 207 } PACKED CSW;
boonshen 0:a35c40f49345 208
boonshen 0:a35c40f49345 209 //state of the bulk-only state machine
boonshen 0:a35c40f49345 210 Stage stage;
boonshen 0:a35c40f49345 211
boonshen 0:a35c40f49345 212 // current CBW
boonshen 0:a35c40f49345 213 CBW cbw;
boonshen 0:a35c40f49345 214
boonshen 0:a35c40f49345 215 // CSW which will be sent
boonshen 0:a35c40f49345 216 CSW csw;
boonshen 0:a35c40f49345 217
boonshen 0:a35c40f49345 218 // addr where will be read or written data
boonshen 0:a35c40f49345 219 uint32_t addr;
boonshen 0:a35c40f49345 220
boonshen 0:a35c40f49345 221 // length of a reading or writing
boonshen 0:a35c40f49345 222 uint32_t length;
boonshen 0:a35c40f49345 223
boonshen 0:a35c40f49345 224 // memory OK (after a memoryVerify)
boonshen 0:a35c40f49345 225 bool memOK;
boonshen 0:a35c40f49345 226
boonshen 0:a35c40f49345 227 // cache in RAM before writing in memory. Useful also to read a block.
boonshen 0:a35c40f49345 228 uint8_t * page;
boonshen 0:a35c40f49345 229
boonshen 0:a35c40f49345 230 int BlockSize;
boonshen 0:a35c40f49345 231 uint64_t MemorySize;
boonshen 0:a35c40f49345 232 uint64_t BlockCount;
boonshen 0:a35c40f49345 233
boonshen 0:a35c40f49345 234 void CBWDecode(uint8_t * buf, uint16_t size);
boonshen 0:a35c40f49345 235 void sendCSW (void);
boonshen 0:a35c40f49345 236 bool inquiryRequest (void);
boonshen 0:a35c40f49345 237 bool write (uint8_t * buf, uint16_t size);
boonshen 0:a35c40f49345 238 bool readFormatCapacity();
boonshen 0:a35c40f49345 239 bool readCapacity (void);
boonshen 0:a35c40f49345 240 bool infoTransfer (void);
boonshen 0:a35c40f49345 241 void memoryRead (void);
boonshen 0:a35c40f49345 242 bool modeSense6 (void);
boonshen 0:a35c40f49345 243 void testUnitReady (void);
boonshen 0:a35c40f49345 244 bool requestSense (void);
boonshen 0:a35c40f49345 245 void memoryVerify (uint8_t * buf, uint16_t size);
boonshen 0:a35c40f49345 246 void memoryWrite (uint8_t * buf, uint16_t size);
boonshen 0:a35c40f49345 247 void reset();
boonshen 0:a35c40f49345 248 void fail();
boonshen 0:a35c40f49345 249 };
boonshen 0:a35c40f49345 250
boonshen 0:a35c40f49345 251 #endif