USB Host Driver with Socket Modem support. Works with revision 323 of mbed-src but broken with any later version.
Dependencies: FATFileSystem
Fork of F401RE-USBHost by
USBHost/USBHALHost2_LPC4088.cpp@26:53970cabf56d, 2015-06-26 (annotated)
- Committer:
- fritz291
- Date:
- Fri Jun 26 19:30:55 2015 +0000
- Revision:
- 26:53970cabf56d
- Parent:
- 18:61554f238584
Fixed small error in testAT function
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 |
18:61554f238584 | 1 | #if defined(TARGET_LPC4088)||defined(TARGET_LPC1768) |
va009039 |
18:61554f238584 | 2 | #include "USBHALHost.h" |
va009039 |
18:61554f238584 | 3 | |
va009039 |
18:61554f238584 | 4 | #undef USB_TEST_ASSERT |
va009039 |
18:61554f238584 | 5 | void usb_test_assert_internal(const char *expr, const char *file, int line); |
va009039 |
18:61554f238584 | 6 | #define USB_TEST_ASSERT(EXPR) while(!(EXPR)){usb_test_assert_internal(#EXPR,__FILE__,__LINE__);} |
va009039 |
18:61554f238584 | 7 | |
va009039 |
18:61554f238584 | 8 | #define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");}while(0); |
va009039 |
18:61554f238584 | 9 | |
va009039 |
18:61554f238584 | 10 | //#define DBG_USE_POSIX_MEMALIGN |
va009039 |
18:61554f238584 | 11 | |
va009039 |
18:61554f238584 | 12 | #ifdef DBG_USE_POSIX_MEMALIGN |
va009039 |
18:61554f238584 | 13 | void* usb_ram_malloc(size_t size, int aligment) |
va009039 |
18:61554f238584 | 14 | { |
va009039 |
18:61554f238584 | 15 | TEST_ASSERT(aligment >= 4); |
va009039 |
18:61554f238584 | 16 | TEST_ASSERT(!(aligment & 3)); |
va009039 |
18:61554f238584 | 17 | void* p; |
va009039 |
18:61554f238584 | 18 | if (posix_memalign(&p, aligment, size) == 0) { |
va009039 |
18:61554f238584 | 19 | return p; |
va009039 |
18:61554f238584 | 20 | } |
va009039 |
18:61554f238584 | 21 | return NULL; |
va009039 |
18:61554f238584 | 22 | } |
va009039 |
18:61554f238584 | 23 | |
va009039 |
18:61554f238584 | 24 | void usb_ram_free(void* p) |
va009039 |
18:61554f238584 | 25 | { |
va009039 |
18:61554f238584 | 26 | free(p); |
va009039 |
18:61554f238584 | 27 | } |
va009039 |
18:61554f238584 | 28 | #else |
va009039 |
18:61554f238584 | 29 | |
va009039 |
18:61554f238584 | 30 | #define CHUNK_SIZE 64 |
va009039 |
18:61554f238584 | 31 | |
va009039 |
18:61554f238584 | 32 | #if defined(TARGET_LPC1768) |
va009039 |
18:61554f238584 | 33 | #define USB_RAM_BASE 0x2007C000 |
va009039 |
18:61554f238584 | 34 | #define USB_RAM_SIZE 0x4000 |
va009039 |
18:61554f238584 | 35 | #define BLOCK_COUNT (USB_RAM_SIZE/CHUNK_SIZE) |
va009039 |
18:61554f238584 | 36 | #elif defined(TARGET_LPC4088) |
va009039 |
18:61554f238584 | 37 | #define USB_RAM_BASE 0x20000000 |
va009039 |
18:61554f238584 | 38 | #define USB_RAM_SIZE 0x4000 |
va009039 |
18:61554f238584 | 39 | #define BLOCK_COUNT (USB_RAM_SIZE/CHUNK_SIZE) |
va009039 |
18:61554f238584 | 40 | #else |
va009039 |
18:61554f238584 | 41 | #error "target error" |
va009039 |
18:61554f238584 | 42 | #endif |
va009039 |
18:61554f238584 | 43 | |
va009039 |
18:61554f238584 | 44 | static uint8_t* ram = NULL; |
va009039 |
18:61554f238584 | 45 | static uint8_t* map; |
va009039 |
18:61554f238584 | 46 | |
va009039 |
18:61554f238584 | 47 | static void usb_ram_init() |
va009039 |
18:61554f238584 | 48 | { |
va009039 |
18:61554f238584 | 49 | USB_INFO("USB_RAM: 0x%p(%d)", USB_RAM_BASE, USB_RAM_SIZE); |
va009039 |
18:61554f238584 | 50 | ram = (uint8_t*)USB_RAM_BASE; |
va009039 |
18:61554f238584 | 51 | USB_TEST_ASSERT((int)ram%256 == 0); |
va009039 |
18:61554f238584 | 52 | map = (uint8_t*)malloc(BLOCK_COUNT); |
va009039 |
18:61554f238584 | 53 | USB_TEST_ASSERT(map); |
va009039 |
18:61554f238584 | 54 | memset(map, 0, BLOCK_COUNT); |
va009039 |
18:61554f238584 | 55 | } |
va009039 |
18:61554f238584 | 56 | |
va009039 |
18:61554f238584 | 57 | // first fit malloc |
va009039 |
18:61554f238584 | 58 | void* usb_ram_malloc(size_t size, int aligment) |
va009039 |
18:61554f238584 | 59 | { |
va009039 |
18:61554f238584 | 60 | USB_TEST_ASSERT(aligment >= 4); |
va009039 |
18:61554f238584 | 61 | USB_TEST_ASSERT(!(aligment & 3)); |
va009039 |
18:61554f238584 | 62 | if (ram == NULL) { |
va009039 |
18:61554f238584 | 63 | usb_ram_init(); |
va009039 |
18:61554f238584 | 64 | } |
va009039 |
18:61554f238584 | 65 | int needs = (size+CHUNK_SIZE-1)/CHUNK_SIZE; |
va009039 |
18:61554f238584 | 66 | void* p = NULL; |
va009039 |
18:61554f238584 | 67 | for(int idx = 0; idx < BLOCK_COUNT;) { |
va009039 |
18:61554f238584 | 68 | bool found = true; |
va009039 |
18:61554f238584 | 69 | for(int i = 0; i < needs; i++) { |
va009039 |
18:61554f238584 | 70 | int block = map[idx + i]; |
va009039 |
18:61554f238584 | 71 | if (block != 0) { |
va009039 |
18:61554f238584 | 72 | idx += block; |
va009039 |
18:61554f238584 | 73 | found = false; |
va009039 |
18:61554f238584 | 74 | break; |
va009039 |
18:61554f238584 | 75 | } |
va009039 |
18:61554f238584 | 76 | } |
va009039 |
18:61554f238584 | 77 | if (!found) { |
va009039 |
18:61554f238584 | 78 | continue; |
va009039 |
18:61554f238584 | 79 | } |
va009039 |
18:61554f238584 | 80 | p = ram+idx*CHUNK_SIZE; |
va009039 |
18:61554f238584 | 81 | if ((int)p % aligment) { |
va009039 |
18:61554f238584 | 82 | idx++; |
va009039 |
18:61554f238584 | 83 | continue; |
va009039 |
18:61554f238584 | 84 | } |
va009039 |
18:61554f238584 | 85 | USB_TEST_ASSERT((idx + needs) <= BLOCK_COUNT); |
va009039 |
18:61554f238584 | 86 | for(int i = 0; i < needs; i++) { |
va009039 |
18:61554f238584 | 87 | map[idx + i] = needs - i; |
va009039 |
18:61554f238584 | 88 | } |
va009039 |
18:61554f238584 | 89 | break; |
va009039 |
18:61554f238584 | 90 | } |
va009039 |
18:61554f238584 | 91 | USB_TEST_ASSERT(p); |
va009039 |
18:61554f238584 | 92 | return p; |
va009039 |
18:61554f238584 | 93 | } |
va009039 |
18:61554f238584 | 94 | |
va009039 |
18:61554f238584 | 95 | void usb_ram_free(void* p) |
va009039 |
18:61554f238584 | 96 | { |
va009039 |
18:61554f238584 | 97 | USB_TEST_ASSERT(p >= ram); |
va009039 |
18:61554f238584 | 98 | USB_TEST_ASSERT(p < (ram+CHUNK_SIZE*BLOCK_COUNT)); |
va009039 |
18:61554f238584 | 99 | int idx = ((int)p-(int)ram)/CHUNK_SIZE; |
va009039 |
18:61554f238584 | 100 | int block = map[idx]; |
va009039 |
18:61554f238584 | 101 | USB_TEST_ASSERT(block >= 1); |
va009039 |
18:61554f238584 | 102 | for(int i =0; i < block; i++) { |
va009039 |
18:61554f238584 | 103 | map[idx + i] = 0; |
va009039 |
18:61554f238584 | 104 | } |
va009039 |
18:61554f238584 | 105 | } |
va009039 |
18:61554f238584 | 106 | |
va009039 |
18:61554f238584 | 107 | #endif // DBG_USE_POSIX_MEMALIGN |
va009039 |
18:61554f238584 | 108 | |
va009039 |
18:61554f238584 | 109 | void print_td(FILE* stream, HCTD* td) |
va009039 |
18:61554f238584 | 110 | { |
va009039 |
18:61554f238584 | 111 | if (td == NULL) { |
va009039 |
18:61554f238584 | 112 | fprintf(stream, "TD %p:\n", td); |
va009039 |
18:61554f238584 | 113 | return; |
va009039 |
18:61554f238584 | 114 | } |
va009039 |
18:61554f238584 | 115 | uint32_t* p = reinterpret_cast<uint32_t*>(td); |
va009039 |
18:61554f238584 | 116 | fprintf(stream, "TD %p: %08X %08X %08X %08X", p, p[0], p[1], p[2], p[3]); |
va009039 |
18:61554f238584 | 117 | fprintf(stream, " ep=%p\n", td->parent); |
va009039 |
18:61554f238584 | 118 | uint8_t* bp = reinterpret_cast<uint8_t*>(p[1]); |
va009039 |
18:61554f238584 | 119 | uint8_t* be = reinterpret_cast<uint8_t*>(p[3]); |
va009039 |
18:61554f238584 | 120 | if (bp) { |
va009039 |
18:61554f238584 | 121 | fprintf(stream, "BF %p:", bp); |
va009039 |
18:61554f238584 | 122 | while(bp <= be) { |
va009039 |
18:61554f238584 | 123 | fprintf(stream, " %02X", *bp); |
va009039 |
18:61554f238584 | 124 | bp++; |
va009039 |
18:61554f238584 | 125 | } |
va009039 |
18:61554f238584 | 126 | fprintf(stream, "\n"); |
va009039 |
18:61554f238584 | 127 | } |
va009039 |
18:61554f238584 | 128 | } |
va009039 |
18:61554f238584 | 129 | |
va009039 |
18:61554f238584 | 130 | void print_ed(FILE* stream, HCED* ed) |
va009039 |
18:61554f238584 | 131 | { |
va009039 |
18:61554f238584 | 132 | uint32_t* p = reinterpret_cast<uint32_t*>(ed); |
va009039 |
18:61554f238584 | 133 | while(p) { |
va009039 |
18:61554f238584 | 134 | fprintf(stream, "ED %p: %08X %08X %08X %08X\n", p, p[0], p[1], p[2], p[3]); |
va009039 |
18:61554f238584 | 135 | HCTD* td = reinterpret_cast<HCTD*>(p[2] & ~3); |
va009039 |
18:61554f238584 | 136 | HCTD* tdtail = reinterpret_cast<HCTD*>(p[1]); |
va009039 |
18:61554f238584 | 137 | while(td != NULL && td != tdtail) { |
va009039 |
18:61554f238584 | 138 | print_td(stream, td); |
va009039 |
18:61554f238584 | 139 | td = td->Next; |
va009039 |
18:61554f238584 | 140 | } |
va009039 |
18:61554f238584 | 141 | p = reinterpret_cast<uint32_t*>(p[3]); |
va009039 |
18:61554f238584 | 142 | } |
va009039 |
18:61554f238584 | 143 | } |
va009039 |
18:61554f238584 | 144 | |
va009039 |
18:61554f238584 | 145 | void print_itd(FILE* stream, HCITD* itd) |
va009039 |
18:61554f238584 | 146 | { |
va009039 |
18:61554f238584 | 147 | if (itd == NULL) { |
va009039 |
18:61554f238584 | 148 | fprintf(stream, "ITD %p:\n", itd); |
va009039 |
18:61554f238584 | 149 | return; |
va009039 |
18:61554f238584 | 150 | } |
va009039 |
18:61554f238584 | 151 | uint32_t* p = reinterpret_cast<uint32_t*>(itd); |
va009039 |
18:61554f238584 | 152 | fprintf(stream, "ITD %p: %08X %08X %08X %08X", p, p[0], p[1], p[2], p[3]); |
va009039 |
18:61554f238584 | 153 | fprintf(stream, " ep=%p\n", itd->parent); |
va009039 |
18:61554f238584 | 154 | uint16_t* offset = reinterpret_cast<uint16_t*>(p+4); |
va009039 |
18:61554f238584 | 155 | fprintf(stream, "ITD %p: %04X %04X %04X %04X %04X %04X %04X %04X\n", offset, |
va009039 |
18:61554f238584 | 156 | offset[0], offset[1], offset[2], offset[3], offset[4], offset[5], offset[6], offset[7]); |
va009039 |
18:61554f238584 | 157 | } |
va009039 |
18:61554f238584 | 158 | |
va009039 |
18:61554f238584 | 159 | void print_ied(FILE* stream, HCED* ed) |
va009039 |
18:61554f238584 | 160 | { |
va009039 |
18:61554f238584 | 161 | uint32_t* p = reinterpret_cast<uint32_t*>(ed); |
va009039 |
18:61554f238584 | 162 | while(p) { |
va009039 |
18:61554f238584 | 163 | fprintf(stream, "ED %p: %08X %08X %08X %08X\n", p, p[0], p[1], p[2], p[3]); |
va009039 |
18:61554f238584 | 164 | HCITD* itd = reinterpret_cast<HCITD*>(p[2] & ~3); |
va009039 |
18:61554f238584 | 165 | HCITD* itdtail = reinterpret_cast<HCITD*>(p[1]); |
va009039 |
18:61554f238584 | 166 | while(itd != NULL && itd != itdtail) { |
va009039 |
18:61554f238584 | 167 | print_itd(stream, itd); |
va009039 |
18:61554f238584 | 168 | itd = itd->Next; |
va009039 |
18:61554f238584 | 169 | } |
va009039 |
18:61554f238584 | 170 | p = reinterpret_cast<uint32_t*>(p[3]); |
va009039 |
18:61554f238584 | 171 | } |
va009039 |
18:61554f238584 | 172 | } |
va009039 |
18:61554f238584 | 173 | |
va009039 |
18:61554f238584 | 174 | void print_bytes(FILE* stream, char* s, uint8_t* buf, int len) |
va009039 |
18:61554f238584 | 175 | { |
va009039 |
18:61554f238584 | 176 | fprintf(stream, "%s %d:", s, len); |
va009039 |
18:61554f238584 | 177 | for(int i = 0; i < len; i++) { |
va009039 |
18:61554f238584 | 178 | fprintf(stream, " %02X", buf[i]); |
va009039 |
18:61554f238584 | 179 | } |
va009039 |
18:61554f238584 | 180 | fprintf(stream, "\n"); |
va009039 |
18:61554f238584 | 181 | } |
va009039 |
18:61554f238584 | 182 | |
va009039 |
18:61554f238584 | 183 | void print_hex(FILE* stream, uint8_t* p, int len) |
va009039 |
18:61554f238584 | 184 | { |
va009039 |
18:61554f238584 | 185 | for(int i = 0; i < len; i++) { |
va009039 |
18:61554f238584 | 186 | if (i%16 == 0) { |
va009039 |
18:61554f238584 | 187 | fprintf(stream, "%p:", p); |
va009039 |
18:61554f238584 | 188 | } |
va009039 |
18:61554f238584 | 189 | fprintf(stream, " %02X", *p); |
va009039 |
18:61554f238584 | 190 | p++; |
va009039 |
18:61554f238584 | 191 | if (i%16 == 15) { |
va009039 |
18:61554f238584 | 192 | fprintf(stream, "\n"); |
va009039 |
18:61554f238584 | 193 | } |
va009039 |
18:61554f238584 | 194 | } |
va009039 |
18:61554f238584 | 195 | fprintf(stream, "\n"); |
va009039 |
18:61554f238584 | 196 | } |
va009039 |
18:61554f238584 | 197 | |
va009039 |
18:61554f238584 | 198 | void assert_print(const char* pf, int line, const char* msg) { |
va009039 |
18:61554f238584 | 199 | printf("\n\n%s@%d %s ASSERT!\n\n", pf, line, msg); |
va009039 |
18:61554f238584 | 200 | exit(1); |
va009039 |
18:61554f238584 | 201 | } |
va009039 |
18:61554f238584 | 202 | |
va009039 |
18:61554f238584 | 203 | #endif // defined(TARGET_LPC4088)||defined(TARGET_LPC1768) |
va009039 |
18:61554f238584 | 204 | |
va009039 |
18:61554f238584 | 205 |