Simple USBHost library for Nucleo F446RE/F411RE/F401RE FRDM-KL46Z/KL25Z/F64F LPC4088/LPC1768
Dependents: F401RE-BTstack_example F401RE-USBHostMSD_HelloWorld
Fork of KL46Z-USBHost by
簡易USBホストライブラリです。
official-USBHostの下位互換で対応プログラムを僅かな修正で動かすことが出来ます。
Platforms
- Nucleo F446RE
- Nucleo F411RE
- Nucleo F401RE
- FRDM-K64F
- FRDM-KL46Z
- FRDM-KL25Z
- LPC4088
- LPC1768
Nucleo F446RE/F411RE/F401REのUSB接続方法
| ST morpho | USB |
|---|---|
| U5V (CN10-8) | VBUS (1 RED) |
| PA11 (CN10-14) | DM (2 WHITE) |
| PA12 (CN10-12) | DP (3 GREEN) |
| GND (CN10-20) | GND (4 BLACK) |
Examples
Import programF446RE-USBHostMouse_HelloWorld
USBHostMouse Hello World for ST-Nucleo-F446RE
Import programF401RE-USBHostMSD_HelloWorld
Simple USBHost MSD(USB flash drive) for Nucleo F401RE/FRDM-KL46Z test program
Import programF401RE-USBHostC270_example
Simple USBHost WebCam test program
Import programK64F_USBHostC270_example
Simple USBHost C270 example
Import programF401RE-BTstack_example
BTstack for Nucleo F401RE/FRDM-KL46Z example program
Import programUSBHostRSSI_example
Bluetooth device discovery example program.
Import programKL46Z-USBHostGPS_HelloWorld
Simple USBHost GPS Dongle Receiver for FRDM-KL46Z test program
USBHost/USBHALHost2_LPC4088.cpp
- Committer:
- va009039
- Date:
- 2016-05-01
- Revision:
- 23:4ab8bc835303
- Parent:
- 18:61554f238584
File content as of revision 23:4ab8bc835303:
#if defined(TARGET_LPC4088)||defined(TARGET_LPC1768)
#include "USBHALHost.h"
#undef USB_TEST_ASSERT
void usb_test_assert_internal(const char *expr, const char *file, int line);
#define USB_TEST_ASSERT(EXPR) while(!(EXPR)){usb_test_assert_internal(#EXPR,__FILE__,__LINE__);}
#define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");}while(0);
//#define DBG_USE_POSIX_MEMALIGN
#ifdef DBG_USE_POSIX_MEMALIGN
void* usb_ram_malloc(size_t size, int aligment)
{
TEST_ASSERT(aligment >= 4);
TEST_ASSERT(!(aligment & 3));
void* p;
if (posix_memalign(&p, aligment, size) == 0) {
return p;
}
return NULL;
}
void usb_ram_free(void* p)
{
free(p);
}
#else
#define CHUNK_SIZE 64
#if defined(TARGET_LPC1768)
#define USB_RAM_BASE 0x2007C000
#define USB_RAM_SIZE 0x4000
#define BLOCK_COUNT (USB_RAM_SIZE/CHUNK_SIZE)
#elif defined(TARGET_LPC4088)
#define USB_RAM_BASE 0x20000000
#define USB_RAM_SIZE 0x4000
#define BLOCK_COUNT (USB_RAM_SIZE/CHUNK_SIZE)
#else
#error "target error"
#endif
static uint8_t* ram = NULL;
static uint8_t* map;
static void usb_ram_init()
{
USB_INFO("USB_RAM: 0x%p(%d)", USB_RAM_BASE, USB_RAM_SIZE);
ram = (uint8_t*)USB_RAM_BASE;
USB_TEST_ASSERT((int)ram%256 == 0);
map = (uint8_t*)malloc(BLOCK_COUNT);
USB_TEST_ASSERT(map);
memset(map, 0, BLOCK_COUNT);
}
// first fit malloc
void* usb_ram_malloc(size_t size, int aligment)
{
USB_TEST_ASSERT(aligment >= 4);
USB_TEST_ASSERT(!(aligment & 3));
if (ram == NULL) {
usb_ram_init();
}
int needs = (size+CHUNK_SIZE-1)/CHUNK_SIZE;
void* p = NULL;
for(int idx = 0; idx < BLOCK_COUNT;) {
bool found = true;
for(int i = 0; i < needs; i++) {
int block = map[idx + i];
if (block != 0) {
idx += block;
found = false;
break;
}
}
if (!found) {
continue;
}
p = ram+idx*CHUNK_SIZE;
if ((int)p % aligment) {
idx++;
continue;
}
USB_TEST_ASSERT((idx + needs) <= BLOCK_COUNT);
for(int i = 0; i < needs; i++) {
map[idx + i] = needs - i;
}
break;
}
USB_TEST_ASSERT(p);
return p;
}
void usb_ram_free(void* p)
{
USB_TEST_ASSERT(p >= ram);
USB_TEST_ASSERT(p < (ram+CHUNK_SIZE*BLOCK_COUNT));
int idx = ((int)p-(int)ram)/CHUNK_SIZE;
int block = map[idx];
USB_TEST_ASSERT(block >= 1);
for(int i =0; i < block; i++) {
map[idx + i] = 0;
}
}
#endif // DBG_USE_POSIX_MEMALIGN
void print_td(FILE* stream, HCTD* td)
{
if (td == NULL) {
fprintf(stream, "TD %p:\n", td);
return;
}
uint32_t* p = reinterpret_cast<uint32_t*>(td);
fprintf(stream, "TD %p: %08X %08X %08X %08X", p, p[0], p[1], p[2], p[3]);
fprintf(stream, " ep=%p\n", td->parent);
uint8_t* bp = reinterpret_cast<uint8_t*>(p[1]);
uint8_t* be = reinterpret_cast<uint8_t*>(p[3]);
if (bp) {
fprintf(stream, "BF %p:", bp);
while(bp <= be) {
fprintf(stream, " %02X", *bp);
bp++;
}
fprintf(stream, "\n");
}
}
void print_ed(FILE* stream, HCED* ed)
{
uint32_t* p = reinterpret_cast<uint32_t*>(ed);
while(p) {
fprintf(stream, "ED %p: %08X %08X %08X %08X\n", p, p[0], p[1], p[2], p[3]);
HCTD* td = reinterpret_cast<HCTD*>(p[2] & ~3);
HCTD* tdtail = reinterpret_cast<HCTD*>(p[1]);
while(td != NULL && td != tdtail) {
print_td(stream, td);
td = td->Next;
}
p = reinterpret_cast<uint32_t*>(p[3]);
}
}
void print_itd(FILE* stream, HCITD* itd)
{
if (itd == NULL) {
fprintf(stream, "ITD %p:\n", itd);
return;
}
uint32_t* p = reinterpret_cast<uint32_t*>(itd);
fprintf(stream, "ITD %p: %08X %08X %08X %08X", p, p[0], p[1], p[2], p[3]);
fprintf(stream, " ep=%p\n", itd->parent);
uint16_t* offset = reinterpret_cast<uint16_t*>(p+4);
fprintf(stream, "ITD %p: %04X %04X %04X %04X %04X %04X %04X %04X\n", offset,
offset[0], offset[1], offset[2], offset[3], offset[4], offset[5], offset[6], offset[7]);
}
void print_ied(FILE* stream, HCED* ed)
{
uint32_t* p = reinterpret_cast<uint32_t*>(ed);
while(p) {
fprintf(stream, "ED %p: %08X %08X %08X %08X\n", p, p[0], p[1], p[2], p[3]);
HCITD* itd = reinterpret_cast<HCITD*>(p[2] & ~3);
HCITD* itdtail = reinterpret_cast<HCITD*>(p[1]);
while(itd != NULL && itd != itdtail) {
print_itd(stream, itd);
itd = itd->Next;
}
p = reinterpret_cast<uint32_t*>(p[3]);
}
}
void print_bytes(FILE* stream, char* s, uint8_t* buf, int len)
{
fprintf(stream, "%s %d:", s, len);
for(int i = 0; i < len; i++) {
fprintf(stream, " %02X", buf[i]);
}
fprintf(stream, "\n");
}
void print_hex(FILE* stream, uint8_t* p, int len)
{
for(int i = 0; i < len; i++) {
if (i%16 == 0) {
fprintf(stream, "%p:", p);
}
fprintf(stream, " %02X", *p);
p++;
if (i%16 == 15) {
fprintf(stream, "\n");
}
}
fprintf(stream, "\n");
}
void assert_print(const char* pf, int line, const char* msg) {
printf("\n\n%s@%d %s ASSERT!\n\n", pf, line, msg);
exit(1);
}
#endif // defined(TARGET_LPC4088)||defined(TARGET_LPC1768)

