@@ -497,7 +497,8 @@ int grainuumDataQueued(struct GrainuumUSB *usb);
 | 
				
			|||||||
 * @api
 | 
					 * @api
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void grainuumProcess(struct GrainuumUSB *usb,
 | 
					void grainuumProcess(struct GrainuumUSB *usb,
 | 
				
			||||||
                     const uint8_t packet[12]);
 | 
					                     const uint8_t packet[12],
 | 
				
			||||||
 | 
					                     uint32_t size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @brief   Initialize the Grainuum USB system.
 | 
					 * @brief   Initialize the Grainuum USB system.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,55 +31,51 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <generated/csr.h>
 | 
					#include <generated/csr.h>
 | 
				
			||||||
#include <grainuum.h>
 | 
					#include <grainuum.h>
 | 
				
			||||||
 | 
					#include <printf.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__attribute__((weak))
 | 
					__attribute__((weak)) void grainuumConnectPre(struct GrainuumUSB *usb)
 | 
				
			||||||
void grainuumConnectPre(struct GrainuumUSB *usb)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  (void)usb;
 | 
					  (void)usb;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
__attribute__((weak))
 | 
					__attribute__((weak)) void grainuumConnectPost(struct GrainuumUSB *usb)
 | 
				
			||||||
void grainuumConnectPost(struct GrainuumUSB *usb)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  (void)usb;
 | 
					  (void)usb;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__attribute__((weak))
 | 
					__attribute__((weak)) void grainuumDisconnectPre(struct GrainuumUSB *usb)
 | 
				
			||||||
void grainuumDisconnectPre(struct GrainuumUSB *usb)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  (void)usb;
 | 
					  (void)usb;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
__attribute__((weak))
 | 
					__attribute__((weak)) void grainuumDisconnectPost(struct GrainuumUSB *usb)
 | 
				
			||||||
void grainuumDisconnectPost(struct GrainuumUSB *usb)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  (void)usb;
 | 
					  (void)usb;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__attribute__((weak))
 | 
					__attribute__((weak)) void grainuumReceivePacket(struct GrainuumUSB *usb)
 | 
				
			||||||
void grainuumReceivePacket(struct GrainuumUSB *usb)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  (void)usb;
 | 
					  (void)usb;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__attribute__((weak))
 | 
					__attribute__((weak)) void grainuumInitPre(struct GrainuumUSB *usb)
 | 
				
			||||||
void grainuumInitPre(struct GrainuumUSB *usb)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  (void)usb;
 | 
					  (void)usb;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__attribute__((weak))
 | 
					__attribute__((weak)) void grainuumInitPost(struct GrainuumUSB *usb)
 | 
				
			||||||
void grainuumInitPost(struct GrainuumUSB *usb)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  (void)usb;
 | 
					  (void)usb;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* --- */
 | 
					/* --- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void grainuum_receive_packet(struct GrainuumUSB *usb) {
 | 
					void grainuum_receive_packet(struct GrainuumUSB *usb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
  grainuumReceivePacket(usb);
 | 
					  grainuumReceivePacket(usb);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int grainuumCaptureI(struct GrainuumUSB *usb, uint8_t samples[67])
 | 
					int grainuumCaptureI(struct GrainuumUSB *usb, uint8_t samples[67])
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
  int ret;
 | 
					  int ret;
 | 
				
			||||||
  const uint8_t nak_pkt[] = {USB_PID_NAK};
 | 
					  const uint8_t nak_pkt[] = {USB_PID_NAK};
 | 
				
			||||||
  const uint8_t ack_pkt[] = {USB_PID_ACK};
 | 
					  const uint8_t ack_pkt[] = {USB_PID_ACK};
 | 
				
			||||||
@@ -133,6 +129,45 @@ int grainuumCaptureI(struct GrainuumUSB *usb, uint8_t samples[67])
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return ret;
 | 
					  return ret;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					  uint8_t obufbuf[128];
 | 
				
			||||||
 | 
					  uint32_t obufbuf_cnt = 0;
 | 
				
			||||||
 | 
					  while (!usb_ep_0_out_obuf_empty_read())
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    uint32_t obh = usb_ep_0_out_obuf_head_read();
 | 
				
			||||||
 | 
					    obufbuf[obufbuf_cnt++] = obh;
 | 
				
			||||||
 | 
					    usb_ep_0_out_obuf_head_write(1);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int i;
 | 
				
			||||||
 | 
					  static int loops;
 | 
				
			||||||
 | 
					  uint8_t last_tok = usb_ep_0_out_last_tok_read();
 | 
				
			||||||
 | 
					  printf("i: %d  b: %d olt: %02x  --", loops, obufbuf_cnt, last_tok); //obe: %d  obh: %02x\n", i, obe, obh);
 | 
				
			||||||
 | 
					  for (i = 0; i < obufbuf_cnt; i++)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    printf(" %02x", obufbuf[i]);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  printf("\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  usb_ep_0_out_ev_pending_write((1 << 1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Response
 | 
				
			||||||
 | 
					  if (!usb_ep_0_in_ibuf_empty_read())
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    printf("USB ibuf still has data\n");
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  uint32_t usb_in_pending = usb_ep_0_out_ev_pending_read();
 | 
				
			||||||
 | 
					  if (usb_in_pending)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    printf("USB EP0 in pending is: %02x\n", usb_in_pending);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  grainuumProcess(usb, obufbuf, obufbuf_cnt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int grainuumInitialized(struct GrainuumUSB *usb)
 | 
					int grainuumInitialized(struct GrainuumUSB *usb)
 | 
				
			||||||
@@ -143,16 +178,34 @@ int grainuumInitialized(struct GrainuumUSB *usb)
 | 
				
			|||||||
  return usb->initialized;
 | 
					  return usb->initialized;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum usb_responses {
 | 
				
			||||||
 | 
					  USB_STALL = 0b11,
 | 
				
			||||||
 | 
					  USB_ACK   = 0b00,
 | 
				
			||||||
 | 
					  USB_NAK   = 0b01,
 | 
				
			||||||
 | 
					  USB_NONE  = 0b10,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void grainuumWriteQueue(struct GrainuumUSB *usb, int epnum,
 | 
					void grainuumWriteQueue(struct GrainuumUSB *usb, int epnum,
 | 
				
			||||||
                        const void *buffer, int size)
 | 
					                        const void *buffer, int size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  usb->queued_data = buffer;
 | 
					  usb->queued_data = buffer;
 | 
				
			||||||
  usb->queued_epnum = epnum;
 | 
					  usb->queued_epnum = epnum;
 | 
				
			||||||
  usb->queued_size = size;
 | 
					  usb->queued_size = size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int i;
 | 
				
			||||||
 | 
					  const uint8_t *buffer_u8 = buffer;
 | 
				
			||||||
 | 
					  for (i = 0; i < size; i++)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    usb_ep_0_in_ibuf_head_write(buffer_u8[i]);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // Indicate that we respond with an ACK
 | 
				
			||||||
 | 
					  usb_ep_0_in_respond_write(USB_ACK);
 | 
				
			||||||
 | 
					  usb_ep_0_in_ev_pending_write(0xff);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void grainuumInit(struct GrainuumUSB *usb,
 | 
					void grainuumInit(struct GrainuumUSB *usb,
 | 
				
			||||||
                  struct GrainuumConfig *cfg) {
 | 
					                  struct GrainuumConfig *cfg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (usb->initialized)
 | 
					  if (usb->initialized)
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
@@ -168,7 +221,8 @@ void grainuumInit(struct GrainuumUSB *usb,
 | 
				
			|||||||
  grainuumInitPost(usb);
 | 
					  grainuumInitPost(usb);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void grainuumDisconnect(struct GrainuumUSB *usb) {
 | 
					void grainuumDisconnect(struct GrainuumUSB *usb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  grainuumDisconnectPre(usb);
 | 
					  grainuumDisconnectPre(usb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -177,7 +231,8 @@ void grainuumDisconnect(struct GrainuumUSB *usb) {
 | 
				
			|||||||
  grainuumDisconnectPost(usb);
 | 
					  grainuumDisconnectPost(usb);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void grainuumConnect(struct GrainuumUSB *usb) {
 | 
					void grainuumConnect(struct GrainuumUSB *usb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  grainuumConnectPre(usb);
 | 
					  grainuumConnectPre(usb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,6 +29,7 @@
 | 
				
			|||||||
 * authorization.                                                           *
 | 
					 * authorization.                                                           *
 | 
				
			||||||
 ****************************************************************************/
 | 
					 ****************************************************************************/
 | 
				
			||||||
 #include "grainuum.h"
 | 
					 #include "grainuum.h"
 | 
				
			||||||
 | 
					 #include <printf.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef NULL
 | 
					#ifndef NULL
 | 
				
			||||||
#define NULL ((void *)0)
 | 
					#define NULL ((void *)0)
 | 
				
			||||||
@@ -316,13 +317,15 @@ static inline void grainuum_state_parse_token(struct GrainuumState *state,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void grainuumProcess(struct GrainuumUSB *usb,
 | 
					void grainuumProcess(struct GrainuumUSB *usb,
 | 
				
			||||||
                     const uint8_t packet[GRAINUUM_PACKET_SIZE_MAX + 3])
 | 
					                     const uint8_t packet[GRAINUUM_PACKET_SIZE_MAX + 3],
 | 
				
			||||||
 | 
					                     uint32_t size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  uint32_t size = packet[GRAINUUM_PACKET_SIZE_MAX + 3];
 | 
					  // uint32_t size = packet[GRAINUUM_PACKET_SIZE_MAX + 3];
 | 
				
			||||||
  struct GrainuumState *state = &usb->state;
 | 
					  struct GrainuumState *state = &usb->state;
 | 
				
			||||||
  switch(packet[0]) {
 | 
					  switch(packet[0]) {
 | 
				
			||||||
  case USB_PID_SETUP:
 | 
					  case USB_PID_SETUP:
 | 
				
			||||||
 | 
					  printf("Setup packet!\n");
 | 
				
			||||||
    state->packet_type = packet_type_setup;
 | 
					    state->packet_type = packet_type_setup;
 | 
				
			||||||
    grainuum_state_clear_tx(state, 1);
 | 
					    grainuum_state_clear_tx(state, 1);
 | 
				
			||||||
    grainuum_state_parse_token(state, packet + 1);
 | 
					    grainuum_state_parse_token(state, packet + 1);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										66
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										66
									
								
								src/main.c
									
									
									
									
									
								
							@@ -7,13 +7,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <generated/csr.h>
 | 
					#include <generated/csr.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum usb_responses {
 | 
					 | 
				
			||||||
    USB_STALL = 0b11,
 | 
					 | 
				
			||||||
    USB_ACK   = 0b00,
 | 
					 | 
				
			||||||
    USB_NAK   = 0b01,
 | 
					 | 
				
			||||||
    USB_NONE  = 0b10,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void isr(void)
 | 
					void isr(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    unsigned int irqs;
 | 
					    unsigned int irqs;
 | 
				
			||||||
@@ -43,12 +36,6 @@ static void init(void)
 | 
				
			|||||||
    init_printf(NULL, rv_putchar);
 | 
					    init_printf(NULL, rv_putchar);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static uint32_t read_timer(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    timer0_update_value_write(1);
 | 
					 | 
				
			||||||
    return timer0_value_read();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef CSR_USB_EP_0_OUT_EV_PENDING_ADDR
 | 
					#ifdef CSR_USB_EP_0_OUT_EV_PENDING_ADDR
 | 
				
			||||||
struct usb_status
 | 
					struct usb_status
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -86,40 +73,13 @@ static void get_print_status(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (s.out_ev_pending & (1 << 1)) {
 | 
					    if (s.out_ev_pending & (1 << 1)) {
 | 
				
			||||||
        loops++;
 | 
					        loops++;
 | 
				
			||||||
        uint8_t obufbuf[128];
 | 
					        usb_isr();
 | 
				
			||||||
        while (!usb_ep_0_out_obuf_empty_read()) {
 | 
					        // for (i = 0; i < 0x20; i++) {
 | 
				
			||||||
            uint32_t obh = usb_ep_0_out_obuf_head_read();
 | 
					        //     usb_ep_0_in_ibuf_head_write(i);
 | 
				
			||||||
            obufbuf[obufbuf_cnt++] = obh;
 | 
					        // }
 | 
				
			||||||
            usb_ep_0_out_obuf_head_write(1);
 | 
					        // // Indicate that we respond with an ACK
 | 
				
			||||||
        }
 | 
					        // usb_ep_0_in_respond_write(USB_ACK);
 | 
				
			||||||
 | 
					        // usb_ep_0_in_ev_pending_write(0xff);
 | 
				
			||||||
        int i;
 | 
					 | 
				
			||||||
        printf("i: %d  b: %d olt: %02x  --", loops, obufbuf_cnt, s.out_last_tok);//obe: %d  obh: %02x\n", i, obe, obh);
 | 
					 | 
				
			||||||
        for (i = 0; i < obufbuf_cnt; i++) {
 | 
					 | 
				
			||||||
            printf(" %02x", obufbuf[i]);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        printf("\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        usb_ep_0_out_ev_pending_write((1 << 1));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Response
 | 
					 | 
				
			||||||
        if (!usb_ep_0_in_ibuf_empty_read()) {
 | 
					 | 
				
			||||||
            printf("USB ibuf still has data\n");
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        uint32_t usb_in_pending = usb_ep_0_out_ev_pending_read();
 | 
					 | 
				
			||||||
        if (usb_in_pending) {
 | 
					 | 
				
			||||||
            printf("USB EP0 in pending is: %02x\n", usb_in_pending);
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for (i = 0; i < 0x20; i++) {
 | 
					 | 
				
			||||||
            usb_ep_0_in_ibuf_head_write(i);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        // Indicate that we respond with an ACK
 | 
					 | 
				
			||||||
        usb_ep_0_in_respond_write(USB_ACK);
 | 
					 | 
				
			||||||
        usb_ep_0_in_ev_pending_write(0xff);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
@@ -166,26 +126,14 @@ int main(int argc, char **argv)
 | 
				
			|||||||
    printf("Status: %d\n", usb_ep_0_out_obuf_empty_read());
 | 
					    printf("Status: %d\n", usb_ep_0_out_obuf_empty_read());
 | 
				
			||||||
    get_print_status();
 | 
					    get_print_status();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int i = 0;
 | 
					 | 
				
			||||||
    printf("Hello, world!\n");
 | 
					    printf("Hello, world!\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int last_event = 0;
 | 
					    int last_event = 0;
 | 
				
			||||||
    while (1)
 | 
					    while (1)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // unsigned int timer_val_ok = read_timer();
 | 
					 | 
				
			||||||
        // int elapsed(int *last_event, int period)
 | 
					 | 
				
			||||||
        elapsed(&last_event, 1000);
 | 
					        elapsed(&last_event, 1000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unsigned int timer_val_cur;
 | 
					 | 
				
			||||||
        // timer_val_cur = read_timer();
 | 
					 | 
				
			||||||
        // printf("10 PRINT HELLO, WORLD\n");
 | 
					 | 
				
			||||||
        // printf("20 GOTO 10\n");
 | 
					 | 
				
			||||||
        // printf("i: %d\n", i++);
 | 
					 | 
				
			||||||
        // timer_val_cur = read_timer();
 | 
					 | 
				
			||||||
        get_print_status();
 | 
					        get_print_status();
 | 
				
			||||||
        // while (timer0_value_read() != timer_val_ok) {
 | 
					 | 
				
			||||||
        // ;
 | 
					 | 
				
			||||||
        // }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										326
									
								
								src/usb.c
									
									
									
									
									
								
							
							
						
						
									
										326
									
								
								src/usb.c
									
									
									
									
									
								
							@@ -1,9 +1,329 @@
 | 
				
			|||||||
 | 
					#include <grainuum.h>
 | 
				
			||||||
 | 
					#include <usb.h>
 | 
				
			||||||
#include <generated/csr.h>
 | 
					#include <generated/csr.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void usb_init(void) {
 | 
					#define NUM_BUFFERS 4
 | 
				
			||||||
    // usb_pullup_out_write(1);
 | 
					#define BUFFER_SIZE 64
 | 
				
			||||||
 | 
					#define EP_INTERVAL_MS 6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct GrainuumUSB usb;
 | 
				
			||||||
 | 
					static uint8_t usb_buf[67];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint32_t rx_buffer[NUM_BUFFERS][BUFFER_SIZE / sizeof(uint32_t)];
 | 
				
			||||||
 | 
					static uint8_t rx_buffer_head;
 | 
				
			||||||
 | 
					static uint8_t rx_buffer_tail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint32_t rx_buffer_queries = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void set_usb_config_num(struct GrainuumUSB *usb, int configNum)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  (void)usb;
 | 
				
			||||||
 | 
					  (void)configNum;
 | 
				
			||||||
 | 
					  ;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const uint8_t hid_report_descriptor[] = {
 | 
				
			||||||
 | 
					    0x06, 0x00, 0xFF, // (GLOBAL) USAGE_PAGE         0xFF00 Vendor-defined
 | 
				
			||||||
 | 
					    0x09, 0x00,       // (LOCAL)  USAGE              0xFF000000
 | 
				
			||||||
 | 
					    0xA1, 0x01,       // (MAIN)   COLLECTION         0x01 Application (Usage=0xFF000000: Page=Vendor-defined, Usage=, Type=)
 | 
				
			||||||
 | 
					    0x26, 0xFF, 0x00, //   (GLOBAL) LOGICAL_MAXIMUM    0x00FF (255)
 | 
				
			||||||
 | 
					    0x75, 0x08,       //   (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field
 | 
				
			||||||
 | 
					    0x95, 0x08,       //   (GLOBAL) REPORT_COUNT       0x08 (8) Number of fields
 | 
				
			||||||
 | 
					    0x06, 0xFF, 0xFF, //   (GLOBAL) USAGE_PAGE         0xFFFF Vendor-defined
 | 
				
			||||||
 | 
					    0x09, 0x01,       //   (LOCAL)  USAGE              0xFFFF0001
 | 
				
			||||||
 | 
					    0x81, 0x02,       //   (MAIN)   INPUT              0x00000002 (8 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap
 | 
				
			||||||
 | 
					    0x09, 0x01,       //   (LOCAL)  USAGE              0xFFFF0001
 | 
				
			||||||
 | 
					    0x91, 0x02,       //   (MAIN)   OUTPUT             0x00000002 (8 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap
 | 
				
			||||||
 | 
					    0xC0,             // (MAIN)   END_COLLECTION     Application
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct usb_device_descriptor device_descriptor = {
 | 
				
			||||||
 | 
					    .bLength = 18,                //sizeof(struct usb_device_descriptor),
 | 
				
			||||||
 | 
					    .bDescriptorType = DT_DEVICE, /* DEVICE */
 | 
				
			||||||
 | 
					    .bcdUSB = 0x0200,             /* USB 2.0 */
 | 
				
			||||||
 | 
					    .bDeviceClass = 0x00,
 | 
				
			||||||
 | 
					    .bDeviceSubClass = 0x00,
 | 
				
			||||||
 | 
					    .bDeviceProtocol = 0x00,
 | 
				
			||||||
 | 
					    .bMaxPacketSize0 = 0x08, /* 8-byte packets max */
 | 
				
			||||||
 | 
					    .idVendor = 0x1209,
 | 
				
			||||||
 | 
					    .idProduct = 0x9317,
 | 
				
			||||||
 | 
					    .bcdDevice = 0x0114,   /* Device release 1.14 */
 | 
				
			||||||
 | 
					    .iManufacturer = 0x02, /* No manufacturer string */
 | 
				
			||||||
 | 
					    .iProduct = 0x01,      /* Product name in string #2 */
 | 
				
			||||||
 | 
					    .iSerialNumber = 0x03, /* No serial number */
 | 
				
			||||||
 | 
					    .bNumConfigurations = 0x01,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct usb_configuration_descriptor configuration_descriptor = {
 | 
				
			||||||
 | 
					    .bLength = 9, //sizeof(struct usb_configuration_descriptor),
 | 
				
			||||||
 | 
					    .bDescriptorType = DT_CONFIGURATION,
 | 
				
			||||||
 | 
					    .wTotalLength = (9 + /*9 + 9 + 7  +*/ 9 + 9 + 7 + 7) /*
 | 
				
			||||||
 | 
					                  (sizeof(struct usb_configuration_descriptor)
 | 
				
			||||||
 | 
					                + sizeof(struct usb_interface_descriptor)
 | 
				
			||||||
 | 
					                + sizeof(struct usb_hid_descriptor)
 | 
				
			||||||
 | 
					                + sizeof(struct usb_endpoint_descriptor)*/,
 | 
				
			||||||
 | 
					    .bNumInterfaces = 1,
 | 
				
			||||||
 | 
					    .bConfigurationValue = 1,
 | 
				
			||||||
 | 
					    .iConfiguration = 5,
 | 
				
			||||||
 | 
					    .bmAttributes = 0x80, /* Remote wakeup not supported */
 | 
				
			||||||
 | 
					    .bMaxPower = 100 / 2, /* 100 mA (in 2-mA units) */
 | 
				
			||||||
 | 
					    .data = {
 | 
				
			||||||
 | 
					        /* struct usb_interface_descriptor { */
 | 
				
			||||||
 | 
					        /*  uint8_t bLength;            */ 9,
 | 
				
			||||||
 | 
					        /*  uint8_t bDescriptorType;    */ DT_INTERFACE,
 | 
				
			||||||
 | 
					        /*  uint8_t bInterfaceNumber;   */ 0,
 | 
				
			||||||
 | 
					        /*  uint8_t bAlternateSetting;  */ 0,
 | 
				
			||||||
 | 
					        /*  uint8_t bNumEndpoints;      */ 2, /* Two extra EPs */
 | 
				
			||||||
 | 
					        /*  uint8_t bInterfaceClass;    */ 3, /* HID class */
 | 
				
			||||||
 | 
					        /*  uint8_t bInterfaceSubclass; */ 0, /* Boot Device subclass */
 | 
				
			||||||
 | 
					        /*  uint8_t bInterfaceProtocol; */ 0, /* 1 == keyboard, 2 == mouse */
 | 
				
			||||||
 | 
					        /*  uint8_t iInterface;         */ 4, /* String index #4 */
 | 
				
			||||||
 | 
					                                              /* }*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* struct usb_hid_descriptor {        */
 | 
				
			||||||
 | 
					        /*  uint8_t  bLength;                 */ 9,
 | 
				
			||||||
 | 
					        /*  uint8_t  bDescriptorType;         */ DT_HID,
 | 
				
			||||||
 | 
					        /*  uint16_t bcdHID;                  */ 0x11, 0x01,
 | 
				
			||||||
 | 
					        /*  uint8_t  bCountryCode;            */ 0,
 | 
				
			||||||
 | 
					        /*  uint8_t  bNumDescriptors;         */ 1, /* We have only one REPORT */
 | 
				
			||||||
 | 
					        /*  uint8_t  bReportDescriptorType;   */ DT_HID_REPORT,
 | 
				
			||||||
 | 
					        /*  uint16_t wReportDescriptorLength; */ sizeof(hid_report_descriptor),
 | 
				
			||||||
 | 
					        sizeof(hid_report_descriptor) >> 8,
 | 
				
			||||||
 | 
					        /* }                                  */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* struct usb_endpoint_descriptor { */
 | 
				
			||||||
 | 
					        /*  uint8_t  bLength;             */ 7,
 | 
				
			||||||
 | 
					        /*  uint8_t  bDescriptorType;     */ DT_ENDPOINT,
 | 
				
			||||||
 | 
					        /*  uint8_t  bEndpointAddress;    */ 0x81, /* EP1 (IN) */
 | 
				
			||||||
 | 
					        /*  uint8_t  bmAttributes;        */ 3,    /* Interrupt */
 | 
				
			||||||
 | 
					        /*  uint16_t wMaxPacketSize;      */ 0x08, 0x00,
 | 
				
			||||||
 | 
					        /*  uint8_t  bInterval;           */ EP_INTERVAL_MS, /* Every 6 ms */
 | 
				
			||||||
 | 
					                                                             /* }                              */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* struct usb_endpoint_descriptor { */
 | 
				
			||||||
 | 
					        /*  uint8_t  bLength;             */ 7,
 | 
				
			||||||
 | 
					        /*  uint8_t  bDescriptorType;     */ DT_ENDPOINT,
 | 
				
			||||||
 | 
					        /*  uint8_t  bEndpointAddress;    */ 0x01, /* EP1 (OUT) */
 | 
				
			||||||
 | 
					        /*  uint8_t  bmAttributes;        */ 3,    /* Interrupt */
 | 
				
			||||||
 | 
					        /*  uint16_t wMaxPacketSize;      */ 0x08, 0x00,
 | 
				
			||||||
 | 
					        /*  uint8_t  bInterval;           */ EP_INTERVAL_MS, /* Every 6 ms */
 | 
				
			||||||
 | 
					                                                             /* }                              */
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define USB_STR_BUF_LEN 64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint32_t str_buf_storage[USB_STR_BUF_LEN / sizeof(uint32_t)];
 | 
				
			||||||
 | 
					static int send_string_descriptor(const char *str, const void **data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  int len;
 | 
				
			||||||
 | 
					  int max_len;
 | 
				
			||||||
 | 
					  uint8_t *str_buf = (uint8_t *)str_buf_storage;
 | 
				
			||||||
 | 
					  uint8_t *str_offset = str_buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  len = strlen(str);
 | 
				
			||||||
 | 
					  max_len = (USB_STR_BUF_LEN / 2) - 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (len > max_len)
 | 
				
			||||||
 | 
					    len = max_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  *str_offset++ = (len * 2) + 2; // Two bytes for length count
 | 
				
			||||||
 | 
					  *str_offset++ = DT_STRING;     // Sending a string descriptor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  while (len--)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    *str_offset++ = *str++;
 | 
				
			||||||
 | 
					    *str_offset++ = 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  *data = str_buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Return the size, which is stored in the first byte of the output data.
 | 
				
			||||||
 | 
					  return str_buf[0];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int get_string_descriptor(struct GrainuumUSB *usb,
 | 
				
			||||||
 | 
					                                 uint32_t num,
 | 
				
			||||||
 | 
					                                 const void **data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static const uint8_t en_us[] = {0x04, DT_STRING, 0x09, 0x04};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  (void)usb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (num == 0)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    *data = en_us;
 | 
				
			||||||
 | 
					    return sizeof(en_us);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Product
 | 
				
			||||||
 | 
					  if (num == 1)
 | 
				
			||||||
 | 
					    return send_string_descriptor("Palawan Bootloader", data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (num == 2)
 | 
				
			||||||
 | 
					    return send_string_descriptor("21", data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (num == 3)
 | 
				
			||||||
 | 
					    return send_string_descriptor("1236", data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (num == 4)
 | 
				
			||||||
 | 
					    return send_string_descriptor("12345", data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (num == 5)
 | 
				
			||||||
 | 
					    return send_string_descriptor("54", data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (num == 6)
 | 
				
			||||||
 | 
					    return send_string_descriptor("12345678901234", data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int get_device_descriptor(struct GrainuumUSB *usb,
 | 
				
			||||||
 | 
					                                 uint32_t num,
 | 
				
			||||||
 | 
					                                 const void **data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  (void)usb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (num == 0)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    *data = &device_descriptor;
 | 
				
			||||||
 | 
					    return sizeof(device_descriptor);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int get_hid_report_descriptor(struct GrainuumUSB *usb,
 | 
				
			||||||
 | 
					                                     uint32_t num,
 | 
				
			||||||
 | 
					                                     const void **data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  (void)usb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (num == 0)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    *data = &hid_report_descriptor;
 | 
				
			||||||
 | 
					    return sizeof(hid_report_descriptor);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int get_configuration_descriptor(struct GrainuumUSB *usb,
 | 
				
			||||||
 | 
					                                        uint32_t num,
 | 
				
			||||||
 | 
					                                        const void **data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  (void)usb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (num == 0)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    *data = &configuration_descriptor;
 | 
				
			||||||
 | 
					    return configuration_descriptor.wTotalLength;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int get_descriptor(struct GrainuumUSB *usb,
 | 
				
			||||||
 | 
					                          const void *packet,
 | 
				
			||||||
 | 
					                          const void **response)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const struct usb_setup_packet *setup = packet;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  switch (setup->wValueH)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  case DT_DEVICE:
 | 
				
			||||||
 | 
					    return get_device_descriptor(usb, setup->wValueL, response);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  case DT_STRING:
 | 
				
			||||||
 | 
					    return get_string_descriptor(usb, setup->wValueL, response);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  case DT_CONFIGURATION:
 | 
				
			||||||
 | 
					    return get_configuration_descriptor(usb, setup->wValueL, response);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  case DT_HID_REPORT:
 | 
				
			||||||
 | 
					    return get_hid_report_descriptor(usb, setup->wValueL, response);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void *get_usb_rx_buffer(struct GrainuumUSB *usb,
 | 
				
			||||||
 | 
					                               uint8_t epNum,
 | 
				
			||||||
 | 
					                               int32_t *size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  (void)usb;
 | 
				
			||||||
 | 
					  (void)epNum;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (size)
 | 
				
			||||||
 | 
					    *size = sizeof(rx_buffer[0]);
 | 
				
			||||||
 | 
					  rx_buffer_queries++;
 | 
				
			||||||
 | 
					  return rx_buffer[rx_buffer_head];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int received_data(struct GrainuumUSB *usb,
 | 
				
			||||||
 | 
					                         uint8_t epNum,
 | 
				
			||||||
 | 
					                         uint32_t bytes,
 | 
				
			||||||
 | 
					                         const void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  (void)usb;
 | 
				
			||||||
 | 
					  (void)epNum;
 | 
				
			||||||
 | 
					  (void)bytes;
 | 
				
			||||||
 | 
					  (void)data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (epNum == 1)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    rx_buffer_head = (rx_buffer_head + 1) & (NUM_BUFFERS - 1);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Return 0, indicating this packet is complete. */
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int send_data_finished(struct GrainuumUSB *usb, int result)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  (void)usb;
 | 
				
			||||||
 | 
					  (void)result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct GrainuumConfig cfg = {
 | 
				
			||||||
 | 
					    .getDescriptor = get_descriptor,
 | 
				
			||||||
 | 
					    .getReceiveBuffer = get_usb_rx_buffer,
 | 
				
			||||||
 | 
					    .receiveData = received_data,
 | 
				
			||||||
 | 
					    .sendDataFinished = send_data_finished,
 | 
				
			||||||
 | 
					    .setConfigNum = set_usb_config_num,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void usb_isr(void) {
 | 
					void usb_isr(void) {
 | 
				
			||||||
 | 
					    grainuumCaptureI(&usb, usb_buf);
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void usb_init(void) {
 | 
				
			||||||
 | 
					    grainuumInit(&usb, &cfg);
 | 
				
			||||||
 | 
					    grainuumConnect(&usb);
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void usbPhyWriteI(const struct GrainuumUSB *usb, const void *buffer, uint32_t size) {
 | 
				
			||||||
 | 
					    (void)usb;
 | 
				
			||||||
 | 
					    const uint8_t *ubuffer = (const uint8_t *)buffer;
 | 
				
			||||||
 | 
					    uint32_t i = 0;
 | 
				
			||||||
 | 
					    while (i < size)
 | 
				
			||||||
 | 
					        usb_obuf_head_write(ubuffer[i]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int usbPhyReadI(const struct GrainuumUSB *usb, uint8_t *samples) {
 | 
				
			||||||
 | 
					    (void)usb;
 | 
				
			||||||
 | 
					    int count = 0;
 | 
				
			||||||
 | 
					    while (!usb_ibuf_empty_read()) {
 | 
				
			||||||
 | 
					        samples[count++] = usb_ibuf_head_read();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return count;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										75
									
								
								third_party/libbase/libc.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										75
									
								
								third_party/libbase/libc.c
									
									
									
									
										vendored
									
									
								
							@@ -40,3 +40,78 @@ strlen(const char *str)
 | 
				
			|||||||
		;
 | 
							;
 | 
				
			||||||
	return (s - str);
 | 
						return (s - str);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * memcpy - Copies one area of memory to another
 | 
				
			||||||
 | 
					 * @dest: Destination
 | 
				
			||||||
 | 
					 * @src: Source
 | 
				
			||||||
 | 
					 * @n: The size to copy.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void *memcpy(void *to, const void *from, size_t n)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						void *xto = to;
 | 
				
			||||||
 | 
						size_t temp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(!n)
 | 
				
			||||||
 | 
							return xto;
 | 
				
			||||||
 | 
						if((long)to & 1) {
 | 
				
			||||||
 | 
							char *cto = to;
 | 
				
			||||||
 | 
							const char *cfrom = from;
 | 
				
			||||||
 | 
							*cto++ = *cfrom++;
 | 
				
			||||||
 | 
							to = cto;
 | 
				
			||||||
 | 
							from = cfrom;
 | 
				
			||||||
 | 
							n--;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if((long)from & 1) {
 | 
				
			||||||
 | 
							char *cto = to;
 | 
				
			||||||
 | 
							const char *cfrom = from;
 | 
				
			||||||
 | 
							for (; n; n--)
 | 
				
			||||||
 | 
								*cto++ = *cfrom++;
 | 
				
			||||||
 | 
							return xto;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if(n > 2 && (long)to & 2) {
 | 
				
			||||||
 | 
							short *sto = to;
 | 
				
			||||||
 | 
							const short *sfrom = from;
 | 
				
			||||||
 | 
							*sto++ = *sfrom++;
 | 
				
			||||||
 | 
							to = sto;
 | 
				
			||||||
 | 
							from = sfrom;
 | 
				
			||||||
 | 
							n -= 2;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if((long)from & 2) {
 | 
				
			||||||
 | 
							short *sto = to;
 | 
				
			||||||
 | 
							const short *sfrom = from;
 | 
				
			||||||
 | 
							temp = n >> 1;
 | 
				
			||||||
 | 
							for (; temp; temp--)
 | 
				
			||||||
 | 
								*sto++ = *sfrom++;
 | 
				
			||||||
 | 
							to = sto;
 | 
				
			||||||
 | 
							from = sfrom;
 | 
				
			||||||
 | 
							if(n & 1) {
 | 
				
			||||||
 | 
								char *cto = to;
 | 
				
			||||||
 | 
								const char *cfrom = from;
 | 
				
			||||||
 | 
								*cto = *cfrom;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return xto;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						temp = n >> 2;
 | 
				
			||||||
 | 
						if(temp) {
 | 
				
			||||||
 | 
							long *lto = to;
 | 
				
			||||||
 | 
							const long *lfrom = from;
 | 
				
			||||||
 | 
							for(; temp; temp--)
 | 
				
			||||||
 | 
								*lto++ = *lfrom++;
 | 
				
			||||||
 | 
							to = lto;
 | 
				
			||||||
 | 
							from = lfrom;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if(n & 2) {
 | 
				
			||||||
 | 
							short *sto = to;
 | 
				
			||||||
 | 
							const short *sfrom = from;
 | 
				
			||||||
 | 
							*sto++ = *sfrom++;
 | 
				
			||||||
 | 
							to = sto;
 | 
				
			||||||
 | 
							from = sfrom;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if(n & 1) {
 | 
				
			||||||
 | 
							char *cto = to;
 | 
				
			||||||
 | 
							const char *cfrom = from;
 | 
				
			||||||
 | 
							*cto = *cfrom;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return xto;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										325
									
								
								third_party/printf.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										325
									
								
								third_party/printf.c
									
									
									
									
										vendored
									
									
								
							@@ -31,215 +31,232 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "printf.h"
 | 
					#include "printf.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef void (*putcf) (void*,char);
 | 
					typedef void (*putcf)(void *, char);
 | 
				
			||||||
static putcf stdout_putf;
 | 
					static putcf stdout_putf;
 | 
				
			||||||
static void* stdout_putp;
 | 
					static void *stdout_putp;
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef PRINTF_LONG_SUPPORT
 | 
					#ifdef PRINTF_LONG_SUPPORT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void uli2a(unsigned long int num, unsigned int base, int uc,char * bf)
 | 
					static void uli2a(unsigned long int num, unsigned int base, int uc, char *bf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int n = 0;
 | 
				
			||||||
 | 
						unsigned int d = 1;
 | 
				
			||||||
 | 
						while (num / d >= base)
 | 
				
			||||||
 | 
							d *= base;
 | 
				
			||||||
 | 
						while (d != 0)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
	int n=0;
 | 
					 | 
				
			||||||
	unsigned int d=1;
 | 
					 | 
				
			||||||
	while (num/d >= base)
 | 
					 | 
				
			||||||
		d*=base;		 
 | 
					 | 
				
			||||||
	while (d!=0) {
 | 
					 | 
				
			||||||
		int dgt = num / d;
 | 
							int dgt = num / d;
 | 
				
			||||||
		num%=d;
 | 
							num %= d;
 | 
				
			||||||
		d/=base;
 | 
							d /= base;
 | 
				
			||||||
		if (n || dgt>0|| d==0) {
 | 
							if (n || dgt > 0 || d == 0)
 | 
				
			||||||
			*bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10);
 | 
							{
 | 
				
			||||||
 | 
								*bf++ = dgt + (dgt < 10 ? '0' : (uc ? 'A' : 'a') - 10);
 | 
				
			||||||
			++n;
 | 
								++n;
 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	*bf=0;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						*bf = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void li2a (long num, char * bf)
 | 
					static void li2a(long num, char *bf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (num < 0)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
	if (num<0) {
 | 
							num = -num;
 | 
				
			||||||
		num=-num;
 | 
					 | 
				
			||||||
		*bf++ = '-';
 | 
							*bf++ = '-';
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	uli2a(num,10,0,bf);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						uli2a(num, 10, 0, bf);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void ui2a(unsigned int num, unsigned int base, int uc,char * bf)
 | 
					static void ui2a(unsigned int num, unsigned int base, int uc, char *bf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int n = 0;
 | 
				
			||||||
 | 
						unsigned int d = 1;
 | 
				
			||||||
 | 
						while (num / d >= base)
 | 
				
			||||||
 | 
							d *= base;
 | 
				
			||||||
 | 
						while (d != 0)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
	int n=0;
 | 
					 | 
				
			||||||
	unsigned int d=1;
 | 
					 | 
				
			||||||
	while (num/d >= base)
 | 
					 | 
				
			||||||
		d*=base;		
 | 
					 | 
				
			||||||
	while (d!=0) {
 | 
					 | 
				
			||||||
		int dgt = num / d;
 | 
							int dgt = num / d;
 | 
				
			||||||
		num%= d;
 | 
							num %= d;
 | 
				
			||||||
		d/=base;
 | 
							d /= base;
 | 
				
			||||||
		if (n || dgt>0 || d==0) {
 | 
							if (n || dgt > 0 || d == 0)
 | 
				
			||||||
			*bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10);
 | 
							{
 | 
				
			||||||
 | 
								*bf++ = dgt + (dgt < 10 ? '0' : (uc ? 'A' : 'a') - 10);
 | 
				
			||||||
			++n;
 | 
								++n;
 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	*bf=0;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						*bf = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void i2a (int num, char * bf)
 | 
					static void i2a(int num, char *bf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (num < 0)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
	if (num<0) {
 | 
							num = -num;
 | 
				
			||||||
		num=-num;
 | 
					 | 
				
			||||||
		*bf++ = '-';
 | 
							*bf++ = '-';
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	ui2a(num,10,0,bf);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						ui2a(num, 10, 0, bf);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int a2d(char ch)
 | 
					static int a2d(char ch)
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	if (ch>='0' && ch<='9') 
 | 
						if (ch >= '0' && ch <= '9')
 | 
				
			||||||
		return ch-'0';
 | 
							return ch - '0';
 | 
				
			||||||
	else if (ch>='a' && ch<='f')
 | 
						else if (ch >= 'a' && ch <= 'f')
 | 
				
			||||||
		return ch-'a'+10;
 | 
							return ch - 'a' + 10;
 | 
				
			||||||
	else if (ch>='A' && ch<='F')
 | 
						else if (ch >= 'A' && ch <= 'F')
 | 
				
			||||||
		return ch-'A'+10;
 | 
							return ch - 'A' + 10;
 | 
				
			||||||
	else return -1;
 | 
						else
 | 
				
			||||||
	}
 | 
							return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char a2i(char ch, char** src,int base,int* nump)
 | 
					static char a2i(char ch, char **src, int base, int *nump)
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	char* p= *src;
 | 
						char *p = *src;
 | 
				
			||||||
	int num=0;
 | 
						int num = 0;
 | 
				
			||||||
	int digit;
 | 
						int digit;
 | 
				
			||||||
	while ((digit=a2d(ch))>=0) {
 | 
						while ((digit = a2d(ch)) >= 0)
 | 
				
			||||||
		if (digit>base) break;
 | 
					 | 
				
			||||||
		num=num*base+digit;
 | 
					 | 
				
			||||||
		ch=*p++;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	*src=p;
 | 
					 | 
				
			||||||
	*nump=num;
 | 
					 | 
				
			||||||
	return ch;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void putchw(void* putp,putcf putf,int n, char z, char* bf)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
	char fc=z? '0' : ' ';
 | 
							if (digit > base)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							num = num * base + digit;
 | 
				
			||||||
 | 
							ch = *p++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						*src = p;
 | 
				
			||||||
 | 
						*nump = num;
 | 
				
			||||||
 | 
						return ch;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void putchw(void *putp, putcf putf, int n, char z, char *bf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char fc = z ? '0' : ' ';
 | 
				
			||||||
	char ch;
 | 
						char ch;
 | 
				
			||||||
	char* p=bf;
 | 
						char *p = bf;
 | 
				
			||||||
	while (*p++ && n > 0)
 | 
						while (*p++ && n > 0)
 | 
				
			||||||
		n--;
 | 
							n--;
 | 
				
			||||||
	while (n-- > 0)
 | 
						while (n-- > 0)
 | 
				
			||||||
		putf(putp,fc);
 | 
							putf(putp, fc);
 | 
				
			||||||
	while ((ch= *bf++))
 | 
						while ((ch = *bf++))
 | 
				
			||||||
		putf(putp,ch);
 | 
							putf(putp, ch);
 | 
				
			||||||
	}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void tfp_format(void* putp,putcf putf,char *fmt, va_list va)
 | 
					void tfp_format(void *putp, putcf putf, char *fmt, va_list va)
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	char bf[12];
 | 
						char bf[12];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char ch;
 | 
						char ch;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while ((ch = *(fmt++)))
 | 
				
			||||||
	while ((ch=*(fmt++))) {
 | 
						{
 | 
				
			||||||
		if (ch!='%') 
 | 
							if (ch != '%')
 | 
				
			||||||
			putf(putp,ch);
 | 
								putf(putp, ch);
 | 
				
			||||||
		else {
 | 
							else
 | 
				
			||||||
			char lz=0;
 | 
							{
 | 
				
			||||||
#ifdef 	PRINTF_LONG_SUPPORT
 | 
								char lz = 0;
 | 
				
			||||||
			char lng=0;
 | 
					#ifdef PRINTF_LONG_SUPPORT
 | 
				
			||||||
 | 
								char lng = 0;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
			int w=0;
 | 
								int w = 0;
 | 
				
			||||||
			ch=*(fmt++);
 | 
								ch = *(fmt++);
 | 
				
			||||||
			if (ch=='0') {
 | 
								if (ch == '0')
 | 
				
			||||||
				ch=*(fmt++);
 | 
								{
 | 
				
			||||||
				lz=1;
 | 
									ch = *(fmt++);
 | 
				
			||||||
				}
 | 
									lz = 1;
 | 
				
			||||||
			if (ch>='0' && ch<='9') {
 | 
								}
 | 
				
			||||||
				ch=a2i(ch,&fmt,10,&w);
 | 
								if (ch >= '0' && ch <= '9')
 | 
				
			||||||
				}
 | 
								{
 | 
				
			||||||
#ifdef 	PRINTF_LONG_SUPPORT
 | 
									ch = a2i(ch, &fmt, 10, &w);
 | 
				
			||||||
			if (ch=='l') {
 | 
								}
 | 
				
			||||||
				ch=*(fmt++);
 | 
					#ifdef PRINTF_LONG_SUPPORT
 | 
				
			||||||
				lng=1;
 | 
								if (ch == 'l')
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									ch = *(fmt++);
 | 
				
			||||||
 | 
									lng = 1;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
			switch (ch) {
 | 
								switch (ch)
 | 
				
			||||||
				case 0: 
 | 
								{
 | 
				
			||||||
					goto abort;
 | 
								case 0:
 | 
				
			||||||
				case 'u' : {
 | 
									goto abort;
 | 
				
			||||||
#ifdef 	PRINTF_LONG_SUPPORT
 | 
								case 'u':
 | 
				
			||||||
					if (lng)
 | 
								{
 | 
				
			||||||
						uli2a(va_arg(va, unsigned long int),10,0,bf);
 | 
					#ifdef PRINTF_LONG_SUPPORT
 | 
				
			||||||
					else
 | 
									if (lng)
 | 
				
			||||||
 | 
										uli2a(va_arg(va, unsigned long int), 10, 0, bf);
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
					ui2a(va_arg(va, unsigned int),10,0,bf);
 | 
										ui2a(va_arg(va, unsigned int), 10, 0, bf);
 | 
				
			||||||
					putchw(putp,putf,w,lz,bf);
 | 
									putchw(putp, putf, w, lz, bf);
 | 
				
			||||||
					break;
 | 
									break;
 | 
				
			||||||
					}
 | 
								}
 | 
				
			||||||
				case 'd' :  {
 | 
								case 'd':
 | 
				
			||||||
#ifdef 	PRINTF_LONG_SUPPORT
 | 
								{
 | 
				
			||||||
					if (lng)
 | 
					#ifdef PRINTF_LONG_SUPPORT
 | 
				
			||||||
						li2a(va_arg(va, unsigned long int),bf);
 | 
									if (lng)
 | 
				
			||||||
					else
 | 
										li2a(va_arg(va, unsigned long int), bf);
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
					i2a(va_arg(va, int),bf);
 | 
										i2a(va_arg(va, int), bf);
 | 
				
			||||||
					putchw(putp,putf,w,lz,bf);
 | 
									putchw(putp, putf, w, lz, bf);
 | 
				
			||||||
					break;
 | 
									break;
 | 
				
			||||||
					}
 | 
								}
 | 
				
			||||||
				case 'x': case 'X' : 
 | 
								case 'x':
 | 
				
			||||||
#ifdef 	PRINTF_LONG_SUPPORT
 | 
								case 'X':
 | 
				
			||||||
					if (lng)
 | 
					#ifdef PRINTF_LONG_SUPPORT
 | 
				
			||||||
						uli2a(va_arg(va, unsigned long int),16,(ch=='X'),bf);
 | 
									if (lng)
 | 
				
			||||||
					else
 | 
										uli2a(va_arg(va, unsigned long int), 16, (ch == 'X'), bf);
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
					ui2a(va_arg(va, unsigned int),16,(ch=='X'),bf);
 | 
										ui2a(va_arg(va, unsigned int), 16, (ch == 'X'), bf);
 | 
				
			||||||
					putchw(putp,putf,w,lz,bf);
 | 
									putchw(putp, putf, w, lz, bf);
 | 
				
			||||||
					break;
 | 
									break;
 | 
				
			||||||
				case 'c' : 
 | 
								case 'c':
 | 
				
			||||||
					putf(putp,(char)(va_arg(va, int)));
 | 
									putf(putp, (char)(va_arg(va, int)));
 | 
				
			||||||
					break;
 | 
									break;
 | 
				
			||||||
				case 's' : 
 | 
								case 's':
 | 
				
			||||||
					putchw(putp,putf,w,0,va_arg(va, char*));
 | 
									putchw(putp, putf, w, 0, va_arg(va, char *));
 | 
				
			||||||
					break;
 | 
									break;
 | 
				
			||||||
				case '%' :
 | 
								case '%':
 | 
				
			||||||
					putf(putp,ch);
 | 
									putf(putp, ch);
 | 
				
			||||||
				default:
 | 
								default:
 | 
				
			||||||
					break;
 | 
									break;
 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	abort:;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					abort:;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void init_printf(void *putp, void (*putf)(void *, char))
 | 
				
			||||||
void init_printf(void* putp,void (*putf) (void*,char))
 | 
					{
 | 
				
			||||||
	{
 | 
						stdout_putf = putf;
 | 
				
			||||||
	stdout_putf=putf;
 | 
						stdout_putp = putp;
 | 
				
			||||||
	stdout_putp=putp;
 | 
					}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
void tfp_printf(char *fmt, ...)
 | 
					void tfp_printf(char *fmt, ...)
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	va_list va;
 | 
						va_list va;
 | 
				
			||||||
	va_start(va,fmt);
 | 
						va_start(va, fmt);
 | 
				
			||||||
	tfp_format(stdout_putp,stdout_putf,fmt,va);
 | 
						tfp_format(stdout_putp, stdout_putf, fmt, va);
 | 
				
			||||||
	va_end(va);
 | 
						va_end(va);
 | 
				
			||||||
	}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void putcp(void* p,char c)
 | 
					static void putcp(void *p, char c)
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	*(*((char**)p))++ = c;
 | 
						*(*((char **)p))++ = c;
 | 
				
			||||||
	}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void tfp_sprintf(char *s, char *fmt, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
void tfp_sprintf(char* s,char *fmt, ...)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	va_list va;
 | 
						va_list va;
 | 
				
			||||||
	va_start(va,fmt);
 | 
						va_start(va, fmt);
 | 
				
			||||||
	tfp_format(&s,putcp,fmt,va);
 | 
						tfp_format(&s, putcp, fmt, va);
 | 
				
			||||||
	putcp(&s,0);
 | 
						putcp(&s, 0);
 | 
				
			||||||
	va_end(va);
 | 
						va_end(va);
 | 
				
			||||||
	}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 int puts(const char *s) {
 | 
				
			||||||
 | 
						 while (*s++)
 | 
				
			||||||
 | 
							stdout_putf(stdout_putp, *s);
 | 
				
			||||||
 | 
						stdout_putf(stdout_putp, '\n');
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
		Reference in New Issue
	
	Block a user