UVC host library
Dependents: LifeCam WebcamServer
usb/usb_mem.cpp@1:ee74af6365b8, 2012-08-03 (annotated)
- Committer:
- va009039
- Date:
- Fri Aug 03 09:54:39 2012 +0000
- Revision:
- 1:ee74af6365b8
- Parent:
- usb/usb_mem.c@0:b0f04c137829
- Child:
- 3:3eb41d749f9a
rename men.c to mem.cpp
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 | 0:b0f04c137829 | 1 | |
va009039 | 0:b0f04c137829 | 2 | /* |
va009039 | 0:b0f04c137829 | 3 | Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) |
va009039 | 0:b0f04c137829 | 4 | |
va009039 | 0:b0f04c137829 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy |
va009039 | 0:b0f04c137829 | 6 | of this software and associated documentation files (the "Software"), to deal |
va009039 | 0:b0f04c137829 | 7 | in the Software without restriction, including without limitation the rights |
va009039 | 0:b0f04c137829 | 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
va009039 | 0:b0f04c137829 | 9 | copies of the Software, and to permit persons to whom the Software is |
va009039 | 0:b0f04c137829 | 10 | furnished to do so, subject to the following conditions: |
va009039 | 0:b0f04c137829 | 11 | |
va009039 | 0:b0f04c137829 | 12 | The above copyright notice and this permission notice shall be included in |
va009039 | 0:b0f04c137829 | 13 | all copies or substantial portions of the Software. |
va009039 | 0:b0f04c137829 | 14 | |
va009039 | 0:b0f04c137829 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
va009039 | 0:b0f04c137829 | 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
va009039 | 0:b0f04c137829 | 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
va009039 | 0:b0f04c137829 | 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
va009039 | 0:b0f04c137829 | 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
va009039 | 0:b0f04c137829 | 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
va009039 | 0:b0f04c137829 | 21 | THE SOFTWARE. |
va009039 | 0:b0f04c137829 | 22 | */ |
va009039 | 0:b0f04c137829 | 23 | #include "mbed.h" |
va009039 | 0:b0f04c137829 | 24 | #define __DEBUG |
va009039 | 0:b0f04c137829 | 25 | #include "mydbg.h" |
va009039 | 0:b0f04c137829 | 26 | #include "usb_mem.h" |
va009039 | 0:b0f04c137829 | 27 | #include "string.h" //For memcpy, memmove, memset |
va009039 | 0:b0f04c137829 | 28 | #include "UsbInc.h" |
va009039 | 0:b0f04c137829 | 29 | |
va009039 | 0:b0f04c137829 | 30 | #define EDS_COUNT 16 |
va009039 | 0:b0f04c137829 | 31 | #define TDS_COUNT 0 |
va009039 | 0:b0f04c137829 | 32 | #define ITDS_COUNT 0 |
va009039 | 0:b0f04c137829 | 33 | #define UTDS_COUNT 32 |
va009039 | 0:b0f04c137829 | 34 | #define BPS_COUNT 9 |
va009039 | 0:b0f04c137829 | 35 | |
va009039 | 0:b0f04c137829 | 36 | #define HCCA_SIZE 0x100 |
va009039 | 0:b0f04c137829 | 37 | #define ED_SIZE 0x10 |
va009039 | 0:b0f04c137829 | 38 | #define TD_SIZE 0x10 |
va009039 | 0:b0f04c137829 | 39 | #define ITD_SIZE 0x20 |
va009039 | 0:b0f04c137829 | 40 | #define UTD_SIZE (32+16) |
va009039 | 0:b0f04c137829 | 41 | #define BP_SIZE (128*8) |
va009039 | 0:b0f04c137829 | 42 | |
va009039 | 0:b0f04c137829 | 43 | #define TOTAL_SIZE (HCCA_SIZE + (EDS_COUNT*ED_SIZE) + (TDS_COUNT*TD_SIZE) + (ITDS_COUNT*ITD_SIZE)) |
va009039 | 0:b0f04c137829 | 44 | |
va009039 | 0:b0f04c137829 | 45 | static volatile __align(256) byte usb_buf[TOTAL_SIZE] __attribute((section("AHBSRAM0"),aligned)); //256 bytes aligned! |
va009039 | 0:b0f04c137829 | 46 | static volatile __align(32) uint8_t usb_utdBuf[UTDS_COUNT*UTD_SIZE] __attribute((section("AHBSRAM0"),aligned)); |
va009039 | 0:b0f04c137829 | 47 | |
va009039 | 0:b0f04c137829 | 48 | static volatile byte* usb_hcca; //256 bytes aligned! |
va009039 | 0:b0f04c137829 | 49 | |
va009039 | 0:b0f04c137829 | 50 | static volatile byte* usb_edBuf; //4 bytes aligned! |
va009039 | 0:b0f04c137829 | 51 | |
va009039 | 0:b0f04c137829 | 52 | static byte usb_edBufAlloc[EDS_COUNT] __attribute((section("AHBSRAM0"),aligned)); |
va009039 | 0:b0f04c137829 | 53 | static uint8_t usb_utdBufAlloc[UTDS_COUNT] __attribute((section("AHBSRAM0"),aligned)); |
va009039 | 0:b0f04c137829 | 54 | static uint8_t usb_bpBufAlloc[BPS_COUNT] __attribute((section("AHBSRAM0"),aligned)); |
va009039 | 0:b0f04c137829 | 55 | static uint8_t usb_bpBuf[BP_SIZE*BPS_COUNT] __attribute((section("AHBSRAM0"),aligned)); |
va009039 | 0:b0f04c137829 | 56 | |
va009039 | 0:b0f04c137829 | 57 | static void utd_init() |
va009039 | 0:b0f04c137829 | 58 | { |
va009039 | 0:b0f04c137829 | 59 | DBG_ASSERT(sizeof(HCTD) == 16); |
va009039 | 0:b0f04c137829 | 60 | DBG_ASSERT(sizeof(HCITD) == 32); |
va009039 | 0:b0f04c137829 | 61 | DBG_ASSERT(sizeof(HCUTD) == 48); |
va009039 | 0:b0f04c137829 | 62 | |
va009039 | 0:b0f04c137829 | 63 | DBG_ASSERT(((uint32_t)usb_utdBuf % 16) == 0); |
va009039 | 0:b0f04c137829 | 64 | DBG_ASSERT(((uint32_t)usb_utdBuf % 32) == 0); |
va009039 | 0:b0f04c137829 | 65 | |
va009039 | 0:b0f04c137829 | 66 | DBG_ASSERT((uint32_t)usb_utdBufAlloc >= 0x2007c000); |
va009039 | 0:b0f04c137829 | 67 | DBG_ASSERT((uint32_t)&usb_utdBufAlloc[UTDS_COUNT] <= 0x2007ffff); |
va009039 | 0:b0f04c137829 | 68 | |
va009039 | 0:b0f04c137829 | 69 | DBG_ASSERT((uint32_t)usb_utdBuf >= 0x2007c000); |
va009039 | 0:b0f04c137829 | 70 | DBG_ASSERT((uint32_t)&usb_utdBuf[UTD_SIZE*UTDS_COUNT] <= 0x2007cfff); |
va009039 | 0:b0f04c137829 | 71 | |
va009039 | 0:b0f04c137829 | 72 | memset(usb_utdBufAlloc, 0x00, UTDS_COUNT); |
va009039 | 0:b0f04c137829 | 73 | } |
va009039 | 0:b0f04c137829 | 74 | |
va009039 | 0:b0f04c137829 | 75 | static void pb_init() |
va009039 | 0:b0f04c137829 | 76 | { |
va009039 | 0:b0f04c137829 | 77 | memset(usb_bpBufAlloc, 0x00, BPS_COUNT); |
va009039 | 0:b0f04c137829 | 78 | |
va009039 | 0:b0f04c137829 | 79 | DBG_ASSERT((uint32_t)usb_bpBufAlloc >= 0x2007c000); |
va009039 | 0:b0f04c137829 | 80 | DBG_ASSERT((uint32_t)&usb_bpBufAlloc[BPS_COUNT] <= 0x2007ffff); |
va009039 | 0:b0f04c137829 | 81 | DBG_ASSERT((uint32_t)usb_bpBuf >= 0x2007c000); |
va009039 | 0:b0f04c137829 | 82 | DBG_ASSERT((uint32_t)(&usb_bpBuf[BP_SIZE*BPS_COUNT]) <= 0x2007ffff); |
va009039 | 0:b0f04c137829 | 83 | } |
va009039 | 0:b0f04c137829 | 84 | |
va009039 | 0:b0f04c137829 | 85 | void usb_mem_init() |
va009039 | 0:b0f04c137829 | 86 | { |
va009039 | 0:b0f04c137829 | 87 | usb_hcca = usb_buf; |
va009039 | 0:b0f04c137829 | 88 | usb_edBuf = usb_buf + HCCA_SIZE; |
va009039 | 0:b0f04c137829 | 89 | memset(usb_edBufAlloc, 0, EDS_COUNT); |
va009039 | 0:b0f04c137829 | 90 | |
va009039 | 0:b0f04c137829 | 91 | utd_init(); |
va009039 | 0:b0f04c137829 | 92 | pb_init(); |
va009039 | 0:b0f04c137829 | 93 | |
va009039 | 0:b0f04c137829 | 94 | DBG("--- Memory Map --- \n"); |
va009039 | 0:b0f04c137829 | 95 | DBG("usb_hcca =%p\n", usb_hcca); |
va009039 | 0:b0f04c137829 | 96 | DBG("usb_edBuf =%p\n", usb_edBuf); |
va009039 | 0:b0f04c137829 | 97 | DBG("usb_utdBuf =%p\n", usb_utdBuf); |
va009039 | 0:b0f04c137829 | 98 | DBG("usb_edBufAlloc =%p\n", usb_edBufAlloc); |
va009039 | 0:b0f04c137829 | 99 | DBG("usb_utdBufAlloc=%p\n", usb_utdBufAlloc); |
va009039 | 0:b0f04c137829 | 100 | DBG("usb_bpBuf =%p\n", usb_bpBuf); |
va009039 | 0:b0f04c137829 | 101 | DBG(" =%p\n", &usb_bpBuf[BP_SIZE*BPS_COUNT]); |
va009039 | 0:b0f04c137829 | 102 | DBG_ASSERT(((uint32_t)usb_hcca % 256) == 0); |
va009039 | 0:b0f04c137829 | 103 | DBG_ASSERT(((uint32_t)usb_edBuf % 16) == 0); |
va009039 | 0:b0f04c137829 | 104 | DBG_ASSERT(((uint32_t)usb_utdBuf % 32) == 0); |
va009039 | 0:b0f04c137829 | 105 | } |
va009039 | 0:b0f04c137829 | 106 | |
va009039 | 0:b0f04c137829 | 107 | volatile byte* usb_get_hcca() |
va009039 | 0:b0f04c137829 | 108 | { |
va009039 | 0:b0f04c137829 | 109 | return usb_hcca; |
va009039 | 0:b0f04c137829 | 110 | } |
va009039 | 0:b0f04c137829 | 111 | |
va009039 | 0:b0f04c137829 | 112 | volatile byte* usb_get_ed() |
va009039 | 0:b0f04c137829 | 113 | { |
va009039 | 0:b0f04c137829 | 114 | int i; |
va009039 | 0:b0f04c137829 | 115 | for(i = 0; i < EDS_COUNT; i++) |
va009039 | 0:b0f04c137829 | 116 | { |
va009039 | 0:b0f04c137829 | 117 | if( !usb_edBufAlloc[i] ) |
va009039 | 0:b0f04c137829 | 118 | { |
va009039 | 0:b0f04c137829 | 119 | usb_edBufAlloc[i] = 1; |
va009039 | 0:b0f04c137829 | 120 | return usb_edBuf + i*ED_SIZE; |
va009039 | 0:b0f04c137829 | 121 | } |
va009039 | 0:b0f04c137829 | 122 | } |
va009039 | 0:b0f04c137829 | 123 | return NULL; //Could not alloc ED |
va009039 | 0:b0f04c137829 | 124 | } |
va009039 | 0:b0f04c137829 | 125 | |
va009039 | 0:b0f04c137829 | 126 | static uint8_t* usb_get_utd(int al) |
va009039 | 0:b0f04c137829 | 127 | { |
va009039 | 0:b0f04c137829 | 128 | DBG_ASSERT(al == 16 || al == 32); // GTD or ITD |
va009039 | 0:b0f04c137829 | 129 | if (al == 16) { |
va009039 | 0:b0f04c137829 | 130 | for(int i = 1; i < UTDS_COUNT; i += 2) { |
va009039 | 0:b0f04c137829 | 131 | if (usb_utdBufAlloc[i] == 0) { |
va009039 | 0:b0f04c137829 | 132 | uint32_t p = (uint32_t)usb_utdBuf + i * UTD_SIZE; |
va009039 | 0:b0f04c137829 | 133 | if ((p % al) == 0) { |
va009039 | 0:b0f04c137829 | 134 | usb_utdBufAlloc[i] = 1; |
va009039 | 0:b0f04c137829 | 135 | DBG_ASSERT((p % al) == 0); |
va009039 | 0:b0f04c137829 | 136 | return (uint8_t*)p; |
va009039 | 0:b0f04c137829 | 137 | } |
va009039 | 0:b0f04c137829 | 138 | } |
va009039 | 0:b0f04c137829 | 139 | } |
va009039 | 0:b0f04c137829 | 140 | } |
va009039 | 0:b0f04c137829 | 141 | for(int i = 0; i < UTDS_COUNT; i++) { |
va009039 | 0:b0f04c137829 | 142 | if (usb_utdBufAlloc[i] == 0) { |
va009039 | 0:b0f04c137829 | 143 | uint32_t p = (uint32_t)usb_utdBuf + i * UTD_SIZE; |
va009039 | 0:b0f04c137829 | 144 | if ((p % al) == 0) { |
va009039 | 0:b0f04c137829 | 145 | usb_utdBufAlloc[i] = 1; |
va009039 | 0:b0f04c137829 | 146 | DBG_ASSERT((p % al) == 0); |
va009039 | 0:b0f04c137829 | 147 | return (uint8_t*)p; |
va009039 | 0:b0f04c137829 | 148 | } |
va009039 | 0:b0f04c137829 | 149 | } |
va009039 | 0:b0f04c137829 | 150 | } |
va009039 | 0:b0f04c137829 | 151 | return NULL; |
va009039 | 0:b0f04c137829 | 152 | } |
va009039 | 0:b0f04c137829 | 153 | |
va009039 | 0:b0f04c137829 | 154 | volatile byte* usb_get_td(uint32_t endpoint) |
va009039 | 0:b0f04c137829 | 155 | { |
va009039 | 0:b0f04c137829 | 156 | DBG_ASSERT(endpoint); |
va009039 | 0:b0f04c137829 | 157 | uint8_t* td = usb_get_utd(16); |
va009039 | 0:b0f04c137829 | 158 | if (td) { |
va009039 | 0:b0f04c137829 | 159 | HCUTD* utd = (HCUTD*)td; |
va009039 | 0:b0f04c137829 | 160 | memset(utd, 0x00, sizeof(HCTD)); |
va009039 | 0:b0f04c137829 | 161 | utd->type = 1; |
va009039 | 0:b0f04c137829 | 162 | utd->UsbEndpoint = endpoint; |
va009039 | 0:b0f04c137829 | 163 | } |
va009039 | 0:b0f04c137829 | 164 | return td; |
va009039 | 0:b0f04c137829 | 165 | } |
va009039 | 0:b0f04c137829 | 166 | |
va009039 | 0:b0f04c137829 | 167 | volatile byte* usb_get_itd(uint32_t endpoint) |
va009039 | 0:b0f04c137829 | 168 | { |
va009039 | 0:b0f04c137829 | 169 | DBG_ASSERT(endpoint); |
va009039 | 0:b0f04c137829 | 170 | uint8_t* itd = usb_get_utd(32); |
va009039 | 0:b0f04c137829 | 171 | if (itd) { |
va009039 | 0:b0f04c137829 | 172 | HCUTD* utd = (HCUTD*)itd; |
va009039 | 0:b0f04c137829 | 173 | memset(utd, 0x00, sizeof(HCITD)); |
va009039 | 0:b0f04c137829 | 174 | utd->type = 2; |
va009039 | 0:b0f04c137829 | 175 | utd->UsbEndpoint = endpoint; |
va009039 | 0:b0f04c137829 | 176 | } |
va009039 | 0:b0f04c137829 | 177 | return itd; |
va009039 | 0:b0f04c137829 | 178 | } |
va009039 | 0:b0f04c137829 | 179 | |
va009039 | 0:b0f04c137829 | 180 | volatile byte* usb_get_bp(int size) |
va009039 | 0:b0f04c137829 | 181 | { |
va009039 | 0:b0f04c137829 | 182 | DBG_ASSERT(size >= 128 && size <= BP_SIZE); |
va009039 | 0:b0f04c137829 | 183 | if (size > BP_SIZE) |
va009039 | 0:b0f04c137829 | 184 | return NULL; |
va009039 | 0:b0f04c137829 | 185 | |
va009039 | 0:b0f04c137829 | 186 | for(int i = 0; i < BPS_COUNT; i++) |
va009039 | 0:b0f04c137829 | 187 | { |
va009039 | 0:b0f04c137829 | 188 | if( !usb_bpBufAlloc[i] ) |
va009039 | 0:b0f04c137829 | 189 | { |
va009039 | 0:b0f04c137829 | 190 | usb_bpBufAlloc[i] = 1; |
va009039 | 0:b0f04c137829 | 191 | return usb_bpBuf + i*BP_SIZE; |
va009039 | 0:b0f04c137829 | 192 | } |
va009039 | 0:b0f04c137829 | 193 | } |
va009039 | 0:b0f04c137829 | 194 | return NULL; //Could not alloc Buffer Page |
va009039 | 0:b0f04c137829 | 195 | } |
va009039 | 0:b0f04c137829 | 196 | |
va009039 | 0:b0f04c137829 | 197 | int usb_bp_size() |
va009039 | 0:b0f04c137829 | 198 | { |
va009039 | 0:b0f04c137829 | 199 | return BP_SIZE; |
va009039 | 0:b0f04c137829 | 200 | } |
va009039 | 0:b0f04c137829 | 201 | |
va009039 | 0:b0f04c137829 | 202 | void usb_free_ed(volatile byte* ed) |
va009039 | 0:b0f04c137829 | 203 | { |
va009039 | 0:b0f04c137829 | 204 | int i; |
va009039 | 0:b0f04c137829 | 205 | i = (ed - usb_edBuf) / ED_SIZE; |
va009039 | 0:b0f04c137829 | 206 | usb_edBufAlloc[i] = 0; |
va009039 | 0:b0f04c137829 | 207 | } |
va009039 | 0:b0f04c137829 | 208 | |
va009039 | 0:b0f04c137829 | 209 | static void usb_free_utd(volatile uint8_t* utd) |
va009039 | 0:b0f04c137829 | 210 | { |
va009039 | 0:b0f04c137829 | 211 | DBG_ASSERT(utd >= usb_utdBuf); |
va009039 | 0:b0f04c137829 | 212 | DBG_ASSERT(utd <= (usb_utdBuf+UTD_SIZE*(UTDS_COUNT-1))); |
va009039 | 0:b0f04c137829 | 213 | DBG_ASSERT(((uint32_t)utd % 16) == 0); |
va009039 | 0:b0f04c137829 | 214 | int i = (utd - usb_utdBuf) / UTD_SIZE; |
va009039 | 0:b0f04c137829 | 215 | DBG_ASSERT(usb_utdBufAlloc[i] == 1); |
va009039 | 0:b0f04c137829 | 216 | usb_utdBufAlloc[i] = 0; |
va009039 | 0:b0f04c137829 | 217 | } |
va009039 | 0:b0f04c137829 | 218 | |
va009039 | 0:b0f04c137829 | 219 | void usb_free_td(volatile byte* td) |
va009039 | 0:b0f04c137829 | 220 | { |
va009039 | 0:b0f04c137829 | 221 | usb_free_utd(td); |
va009039 | 0:b0f04c137829 | 222 | return; |
va009039 | 0:b0f04c137829 | 223 | } |
va009039 | 0:b0f04c137829 | 224 | |
va009039 | 0:b0f04c137829 | 225 | void usb_free_itd(volatile byte* itd) |
va009039 | 0:b0f04c137829 | 226 | { |
va009039 | 0:b0f04c137829 | 227 | usb_free_utd(itd); |
va009039 | 0:b0f04c137829 | 228 | return; |
va009039 | 0:b0f04c137829 | 229 | } |
va009039 | 0:b0f04c137829 | 230 | |
va009039 | 0:b0f04c137829 | 231 | void usb_free_bp(volatile byte* bp) |
va009039 | 0:b0f04c137829 | 232 | { |
va009039 | 0:b0f04c137829 | 233 | DBG_ASSERT(bp >= usb_bpBuf); |
va009039 | 0:b0f04c137829 | 234 | int i; |
va009039 | 0:b0f04c137829 | 235 | i = (bp - usb_bpBuf) / BP_SIZE; |
va009039 | 0:b0f04c137829 | 236 | DBG_ASSERT(usb_bpBufAlloc[i] == 1); |
va009039 | 0:b0f04c137829 | 237 | usb_bpBufAlloc[i] = 0; |
va009039 | 0:b0f04c137829 | 238 | } |
va009039 | 0:b0f04c137829 | 239 | |
va009039 | 0:b0f04c137829 | 240 | bool usb_is_td(volatile byte* td) |
va009039 | 0:b0f04c137829 | 241 | { |
va009039 | 0:b0f04c137829 | 242 | DBG_ASSERT(td); |
va009039 | 0:b0f04c137829 | 243 | HCUTD* utd = (HCUTD*)td; |
va009039 | 0:b0f04c137829 | 244 | DBG_ASSERT(utd->type != 0); |
va009039 | 0:b0f04c137829 | 245 | return utd->type == 1; |
va009039 | 0:b0f04c137829 | 246 | } |
va009039 | 0:b0f04c137829 | 247 | |
va009039 | 0:b0f04c137829 | 248 | bool usb_is_itd(volatile byte* itd) |
va009039 | 0:b0f04c137829 | 249 | { |
va009039 | 0:b0f04c137829 | 250 | DBG_ASSERT(itd); |
va009039 | 0:b0f04c137829 | 251 | HCUTD* utd = (HCUTD*)itd; |
va009039 | 0:b0f04c137829 | 252 | DBG_ASSERT(utd->type != 0); |
va009039 | 0:b0f04c137829 | 253 | return utd->type == 2; |
va009039 | 0:b0f04c137829 | 254 | } |