minilogic / f1c_nonos

Bare metal code examples for Allwinner's F1C100S (F1C200S) SOC
66 stars 21 forks source link

Need host cdc example #3

Open satar1980 opened 8 months ago

satar1980 commented 8 months ago

can you make usb host cdc example....

minilogic commented 8 months ago

Which CDC-device exactly do you mean? I have Holtek HT42B534 usb-uart bridge.

satar1980 commented 8 months ago

i want communicate to stm32f1. i config stm32 as cdc devive. and on the f1c100s i can receive data with this function :

static void mydev_rcv (void) // this fucntion i borrow from void net_rcv (void) : usbh_net.c { struct pbuf* p; int len = USB->RXCOUNT; while(len) { len--; LCD_printf("%c",USB->FIFO[1].byte); } }

but i cannot send data to stm32f1 with :

USB->EP_IDX = 1;
USB->FIFO[1].word32 = 1 | TX_FS | TX_LS;
USB->FIFO[1].word32 = 0;

    USB->EP_IDX = 1;
    USB->FIFO[0].byte = '0';
    USB->TXCSR = 1;
    wait_csr(1, 1, 0, 5000000);

that code i borrow from err_t net_snd (struct netif netif, struct pbuf p) : usbh_net.c can u help me to fix it

======================================================================================= this is the full code :

include

include "usbh_msc.h"

include "usbh_net.h"

include "lcd.h"

uint32_t dev_tim, dev_con = 0;

define BIT(nr) (1UL << (nr))

define TX_FS BIT(31) / First segment of a packet /

define TX_LS BIT(30) / Final segment of a packet /

if 0

define PUTC(ch) putchar(ch)

define PUTS(str) puts(str)

define PUTF(...) printf(__VA_ARGS__)

else

define PUTC(ch)

define PUTS(str)

define PUTF(...)

endif

u8 dev_usb;

/ USB PHY /

void usbh_init (void) { usb_mux(USB_MUX_HOST); CCU->USBPHY_CFG |= 3; CCU->BUS_CLK_GATING0 |= (1 << 24); CCU->BUS_SOFT_RST0 &= ~(1 << 24); CCU->BUS_SOFT_RST0 |= (1 << 24);

if 1

phy_write(0x0c, 0x01, 1); phy_write(0x20, 0x14, 5); //phy_write(0x2A, 0x02, 2); phy_write(0x2A, 0x03, 2);

endif

SYS->CTRL[1] |= 1; USB->ISCR = (USB->ISCR & ~0x70) | (1 << 16); // USBC_BP_ISCR_DPDM_PULLUP_EN USB->ISCR = (USB->ISCR & ~0x70) | (1 << 17); USB->ISCR = (USB->ISCR & ~0xC070) | (2 << 14); // Force internal ID to low USB->ISCR = (USB->ISCR & ~0x70) | (3 << 12); // Force internal VBUS to high USB->BUS_IE = 0; USB->BUS_IS = 0xFF; USB->EP_IE = 0; USB->EP_IS = 0xFFFFFFFF; USB->DEVCTL = 0; USB->EP_IDX = 0; USB->VEND0 = 0; USB->POWER = 0xA0; USB->DEVCTL = 0x81; USB->POWER = 0xF0; USB->DEVCTL = 0x99; dev.cfg = 0; dev_usb = 0; }

void usb_reset (void) { USB->POWER = 0xE8; delay_ms(25); phy_write(0x3c, 2, 2); USB->POWER = 0xF0; phy_write(0x3c, 0, 2); delay_ms(25); USB->EP_IDX = 0; USB->TXCSR = 0; USB->TXFUNCADDR = 0; USB->TXHUBADDR = 0; USB->TXHUBPORT = 0; USB->TXINTERVAL = 0; }

int usbh_myevice_init (DSC_DEV *dev_dsc) {

if(dev_dsc->idVendor != 0x0483 || dev_dsc->idProduct != 0x5740) return KO; set_cfg(1);

USB->EP_IDX = 1; USB->RXFUNCADDR = 1; // address @ bus USB->RXTYPE = (1 << 6) | (2 << 4) | 1; USB->RXMAXP = 512; //dsc.ep1.wMaxPacketSize; USB->RXFIFOADDR = 64 / 8; // addr * 8 USB->RXFIFOSZ = 6; // 2 ^ (size + 3) USB->RXCSR = 0x0080; // clr data toggle USB->TXFUNCADDR = 1; // address @ bus USB->TXTYPE = (1 << 6) | (2 << 4) | 2; // !!! setup speed USB->TXMAXP = 512; //dsc.ep1.wMaxPacketSize; USB->TXFIFOADDR = (512 + 64) / 8; USB->TXFIFOSZ = 6; USB->TXCSR = 0x0048; USB->EP_IDX = 0; dev_tim = timer0_get_ticks() + 100; return OK; }

static void mydev_rcv (void) { struct pbuf* p; int len = USB->RXCOUNT; while(len) { len--; LCD_printf("%c",USB->FIFO[1].byte); } }

static void ep0_send_buf (void buf, u16 len) { u16 ctr; u8 ptr = buf; USB->TXCSR = 0x40; // Serviced RxPktRdy while(len) { while(USB->TXCSR & 2); ctr = len < 64 ? len : 64; len -= ctr; do USB->FIFO[3].byte = *ptr++; while(--ctr); USB->TXCSR = 2; // TxPktRdy } USB->TXCSR = 8; // DataEnd }

void usbh_mydev_handler (u32 isr) { // if(isr 1=& 0x20000) // { //LCDprintf(""); USB->EP_IDX = 1; mydev_rcv(); USB->RXCSR = 32; // }

LCD_printf(".");

USB->EP_IDX = 1;
USB->FIFO[1].word32 = 1 | TX_FS | TX_LS;
USB->FIFO[1].word32 = 0;

    USB->EP_IDX = 1;
    USB->FIFO[0].byte = '0';
    USB->TXCSR = 1;
    wait_csr(1, 1, 0, 5000000);
      delay_ms(200);

}

minilogic commented 8 months ago

I apologize for my long response. If the stm32 device has a full speed USB interface, then the RXTYPE and TXTYPE registers are incorrectly initialized in the usbh_myevice_init function. They must contain (2 << 6), which determine the speed of the interface. Look at the description of this registers in the file: musb

satar1980 commented 8 months ago

iam use this setup but still fail to send data :

int usbh_myevice_init (DSC_DEV *dev_dsc) { // if(dev_dsc->idVendor != 0x0483 || dev_dsc->idProduct != 0x5750) return KO;

if(dev_dsc->idVendor != 0x0483 || dev_dsc->idProduct != 0x5740) return KO; set_cfg(1);

USB->EP_IDX = 1; USB->RXFUNCADDR = 1; // address @ bus USB->RXTYPE = (2 << 6) | (2 << 4) | 1; USB->RXMAXP = 64; //dsc.ep1.wMaxPacketSize; USB->RXFIFOADDR = 64 / 8; // addr * 8 USB->RXFIFOSZ = 6; // 2 ^ (size + 3) USB->RXCSR = 0x0080; // clr data toggle USB->TXFUNCADDR = 1; // address @ bus USB->TXTYPE = (2 << 6) | (2 << 4) | 2; // !!! setup speed USB->TXMAXP = 64; //dsc.ep1.wMaxPacketSize; USB->TXFIFOADDR = (64 + 64) / 8; USB->TXFIFOSZ = 6; USB->TXCSR = 0x0048; USB->EP_IDX = 0; dev_tim = timer0_get_ticks() + 100; return OK; }

static void mydev_rcv (void) { int len = USB->RXCOUNT; LCD_printf("<"); for(int i=0;i<len;i++) { // print char LCD_printf("%c",USB->FIFO[1].byte); } LCD_printf(":%d",len); LCD_printf(">"); }

void send_char (char data) //fail send data { USB->EP_IDX = 1; USB->FIFO[1].byte = data; USB->TXCSR = 1; wait_csr(1, 1, 0, 5000000); }

void usbh_mydev_handler (u32 isr) { USB->EP_IDX = 1; mydev_rcv(); USB->RXCSR = 32; send_char('a'); }

minilogic commented 8 months ago

You have incorrect values ​​for the USB->RXFIFOSZ and USB->TXFIFOSZ registers: 2^(6+3) = 2^9 = 512. You need to do: USB->RXFIFOSZ = 3 and USB->TXFIFOSZ = 3. Accordingly: 2^(3+3) = 2^6 = 64.

satar1980 commented 7 months ago

You have incorrect values ​​for the USB->RXFIFOSZ and USB->TXFIFOSZ registers: 2^(6+3) = 2^9 = 512. You need to do: USB->RXFIFOSZ = 3 and USB->TXFIFOSZ = 3. Accordingly: 2^(3+3) = 2^6 = 64.

I have tried it but still fails.

Is the function below correct ? void send_char (char data) { USB->EP_IDX = 1; USB->FIFO[1].byte = data; USB->TXCSR = 1; wait_csr(1, 1, 0, 5000000); }