コード例 #1
0
ファイル: isr.c プロジェクト: bocui107/freakz
/* VBUS Change interrupt handler */
void intp_vbus_change()
{
	usb_pcb_t *pcb = usb_pcb_get();

	VBUS_INT_CLR();

	if (!pcb->connected) {
		pcb->connected = true;

		/* enabled the USB voltage regulator */
		UHWCON |= (1 << UVREGE);

		/* unfreeze the clock and attach to the bus */
		USBCON &= ~(1 << FRZCLK);
		UDCON  &= ~(1 << DETACH);
	} else {
		/* if we're connected, but VBUS is gone, then detach */
		if (!(USBSTA & (1 << VBUS)))
		{
			/* detach from the bus */
			UDCON  |= (1 << DETACH);

			/* freeze the clock and turn off the USB PLL */
			USBCON |= (1 << FRZCLK);
			PLLCSR = 0;

			/* disable the USB voltage regulator */
			UHWCON &= ~(1 << UVREGE);

			pcb->connected = false;
			pcb->flags = 0;
		}
	}
}
コード例 #2
0
ファイル: cdc.c プロジェクト: alon/chibi-juggling
void cdc_req_handler(req_t *req)
{
    U8 i;
    usb_pcb_t *pcb = usb_pcb_get();
    
    switch (req->req)
    {
    case GET_LINE_CODING:
        if (req->type & (DEVICE_TO_HOST | TYPE_CLASS | RECIPIENT_INTF))
        {
            // send the line coding to the host
            for (i=0; i<LINE_CODE_SZ; i++)
            {
                usb_buf_write(EP_CTRL, line_code[i]);
            }
            ep_write(EP_CTRL);
        }
        break;

    case SET_LINE_CODING:
        if (req->type & (HOST_TO_DEVICE | TYPE_CLASS | RECIPIENT_INTF))
        {
            // wait for the setup data to be sent to the control endpoint
            while (pcb->fifo[EP_CTRL].len == 0)
            {
                // keep the nop for a place to set a breakpoint on and to make it obvious we're
                // waiting for something.
                asm("nop");
            }

            // clear the setup flag if needed
            pcb->flags &= ~(1<<SETUP_DATA_AVAIL);

            // send out a zero-length packet to ack to the host that we received
            // the new line coding
            ep_send_zlp(EP_CTRL);

            // set the new line code. the first 8 bytes in the fifo are just
            // for the setup packet so we want to write the next 7 bytes for the
            // line code.
            for (i=0; i<LINE_CODE_SZ; i++)
            {
                line_code[i] = usb_buf_read(EP_CTRL);
            }
        }
        break;

    case SET_CTRL_LINE_STATE:
        if (req->type & (HOST_TO_DEVICE | TYPE_CLASS | RECIPIENT_INTF))
        {
            ep_send_zlp(EP_CTRL);
        }
        break;

    default:
        ep_set_stall(EP_CTRL);
        break;
    }
}
コード例 #3
0
ファイル: ep.c プロジェクト: alon/chibi-juggling
void ep_clear_stall(U8 ep_num)
{
    usb_pcb_t *pcb = usb_pcb_get();

    pcb->ep_stall &= ~(1 << ep_num);
    ep_select(ep_num);
    UECONX |= (1<<STALLRQC);
}
コード例 #4
0
ファイル: ep.c プロジェクト: alon/chibi-juggling
void ep_set_stall(U8 ep_num)
{
    usb_pcb_t *pcb = usb_pcb_get();

    pcb->ep_stall |= (1 << ep_num);
    ep_select(ep_num);
    UECONX |= (1 << STALLRQ);
}
コード例 #5
0
ファイル: ep.c プロジェクト: pursuitxh/FreakUSB
void ep_read(U8 ep_num)
{
    U8 i, len;
    usb_pcb_t *pcb = usb_pcb_get();

    if( ep_num == 0 )
    {
        len = SI32_USB_A_read_ep0_count( SI32_USB_0 );

        for (i=0; i<len; i++)
        {
            usb_buf_write( ep_num,  SI32_USB_A_read_ep0_fifo_u8( SI32_USB_0 ) );
        }

                   //if( len == 8 )
            //    

        if( 0==SI32_USB_A_read_ep0_count( SI32_USB_0 ) )
        {
            //SI32_USB_A_set_data_end_ep0(SI32_USB_0);
 
        }
    }
    else if( ep_num > 0 )
    {
        if( ep_dir_get( ep_num )  == DIR_IN )
            return;

        len = SI32_USBEP_A_read_data_count( usb_ep[ ep_num - 1 ] );

        if( pcb->fifo[ ep_num ].len + len > MAX_BUF_SZ )
        {
            pcb->pending_data |= ( 1 << ep_num );
            return;
        }

        for (i=0; i<len; i++)
        {
            usb_buf_write(ep_num,  SI32_USBEP_A_read_fifo_u8( usb_ep[ ep_num - 1 ] ));
        }

        //if ( 0==SI32_USBEP_A_read_data_count( usb_ep[ ep_num - 1 ] ))
        //{
            // Clear overrun out overrun if it has occured
            if ( SI32_USBEP_A_has_out_data_overrun_occurred( usb_ep[ ep_num - 1 ] ) )
                SI32_USBEP_A_clear_out_data_overrun( usb_ep[ ep_num - 1 ] );

            SI32_USBEP_A_clear_outpacket_ready( usb_ep[ ep_num - 1 ] );
            pcb->pending_data &= ~(1<<ep_num);
        //}
    }
    if (len > 0)
    {
        pcb->flags |= ( ep_num == 0 ) ? ( 1 << SETUP_DATA_AVAIL ) : ( 1 << RX_DATA_AVAIL );
    }
    //cdc_demo_putchar("a", NULL);
}
コード例 #6
0
ファイル: ep.c プロジェクト: alon/chibi-juggling
void ep_drain_fifo(U8 ep)
{
    U8 byte_cnt;
    usb_pcb_t *pcb = usb_pcb_get();
    
    ep_select(ep);
    byte_cnt = UEBCX;
    if (byte_cnt <= (MAX_BUF_SZ - pcb->fifo[ep].len))
    {
        ep_read(ep);
        pcb->pending_data &= ~(1<<ep);
        FIFOCON_INT_CLR();
    }   
}
コード例 #7
0
ファイル: freakusb_main.c プロジェクト: bocui107/freakz
/*
 * This is the putchar function that is used by avr-libc's printf. We need
 * to hook this function into the stdout file stream using the FDEV_SETUP_STREAM
 * macro in avr-libc. Once the stream is set up, we hook the stream to stdout
 * and we can do printfs via USB.
 */
int freakusb_putchar(char c, FILE *unused)
{
	usb_pcb_t *pcb = usb_pcb_get();

	if (!(pcb->flags & (1 << ENUMERATED)))
		return 0;

	if (c == '\n') {
		usb_buf_write(EP_1, '\n');
		usb_buf_write(EP_1, '\r');
	} else {
		usb_buf_write(EP_1, (U8)c);
	}

	ep_write(EP_1);
	return 0;
}
コード例 #8
0
ファイル: ep.c プロジェクト: alon/chibi-juggling
void ep_read(U8 ep_num)
{
    U8 i, len;
    usb_pcb_t *pcb = usb_pcb_get();

    len = FIFO_BYTE_CNT;

    for (i=0; i<len; i++)
    {
        usb_buf_write(ep_num,  UEDATX);
    }

    if (len > 0)
    {
        pcb->flags |= (ep_num == 0) ? (1<<SETUP_DATA_AVAIL) : (1<<RX_DATA_AVAIL);
    }
}
コード例 #9
0
ファイル: main.c プロジェクト: cardieg/FreakUSB
void rx()
{
    U8 i, c, ep_num, len;
    usb_pcb_t *pcb = usb_pcb_get();

    // get the ep number of any endpoint with pending rx data
    if ((ep_num = usb_buf_data_pending(DIR_OUT)) != 0xFF)
    {
        // get the length of data in the OUT buffer
        len = pcb->fifo[ep_num].len;

        // read out the data in the buffer and echo it back to the host. 
        for (i=0; i<len; i++)
        {
            c = usb_buf_read(ep_num);

            switch (c)
            {
            case '\r':
                // terminate the msg and reset the msg ptr. then send
                // it to the handler for processing.
                *msg_ptr = '\0';
                printf_P(PSTR("\n\r"));
                cmd_parse((char *)msg);
                msg_ptr = msg;
                break;
            
            case '\b':
                usb_buf_write(EP_1, c);
                if (msg_ptr > msg)
                {
                    msg_ptr--;
                }
                break;
            
            default:
                usb_buf_write(EP_1, c);
                *msg_ptr++ = c;
                break;
            }
        }
        pcb->flags |= (1 << TX_DATA_AVAIL);
    }
}
コード例 #10
0
ファイル: ep.c プロジェクト: pursuitxh/FreakUSB
void ep_set_stall(U8 ep_num)
{
    usb_pcb_t *pcb = usb_pcb_get();

    pcb->ep_stall |= (1 << ep_num);
    if( ep_num == 0 )
        SI32_USB_A_send_stall_ep0( SI32_USB_0 );
    else
    {
        if( ep_dir_get( ep_num ) == DIR_IN )
        {
            SI32_USBEP_A_clear_in_stall_sent( usb_ep[ ep_num - 1 ] );
            SI32_USBEP_A_send_in_stall( usb_ep[ ep_num - 1 ] );
        }
        else
        {
            SI32_USBEP_A_clear_out_stall_sent( usb_ep[ ep_num - 1 ] );
            SI32_USBEP_A_send_out_stall( usb_ep[ ep_num - 1 ] );
        }
    }
}
コード例 #11
0
ファイル: ep.c プロジェクト: alon/chibi-juggling
void ep_write(U8 ep_num)
{
    U8 i, ep_size, len;
    usb_pcb_t *pcb = usb_pcb_get();

    ep_select(ep_num);
    ep_size = ep_size_get();
    len = pcb->fifo[ep_num].len;

    // make sure that the tx fifo is ready to receive the out data
    if (ep_num == EP_CTRL)
    {
        while (!TX_FIFO_READY);
    }
    else
    {
        while (!RWAL_INT);
    }

    for (i=0; i<len; i++)
    {
        // check if we've reached the max packet size for the endpoint
        if (i == ep_size)
        {
            // we've filled the max packet size so break and send the data
            break;
        }

        UEDATX = usb_buf_read(ep_num);
    }

    if (ep_num == EP_CTRL)
    {
        while (!TX_FIFO_READY);
    }

    // clearing these two will send the data out
    TX_IN_INT_CLR();
    FIFOCON_INT_CLR();
}
コード例 #12
0
ファイル: ep.c プロジェクト: pursuitxh/FreakUSB
void ep_clear_stall(U8 ep_num)
{
    usb_pcb_t *pcb = usb_pcb_get();

    pcb->ep_stall &= ~(1 << ep_num);
    if( ep_num == 0 )
        SI32_USB_A_clear_stall_sent_ep0( SI32_USB_0 );
    else
    {
        if( ep_dir_get( ep_num ) == DIR_IN )
        {

            SI32_USBEP_A_reset_in_data_toggle( usb_ep[ ep_num - 1 ] );
            SI32_USBEP_A_stop_in_stall( usb_ep[ ep_num - 1 ] );
        }
        else
        {
            SI32_USBEP_A_reset_out_data_toggle( usb_ep[ ep_num - 1 ] );
            SI32_USBEP_A_stop_out_stall( usb_ep[ ep_num - 1 ] );
        }
    }
}
コード例 #13
0
ファイル: dfu.c プロジェクト: cardieg/FreakUSB
void dfu_req_handler(req_t *req)
{
    U8 i;
    usb_pcb_t *pcb = usb_pcb_get();

    switch (req->req)
    {
    case DFU_DETACH:
        if (req->type & (HOST_TO_DEVICE | TYPE_CLASS | RECIPIENT_INTF))
        {
            // wvalue is wTimeout
            // wLength is zero
            // data is none
            dfu_status.bState = appDETACH;
            dfu_status.bStatus = OK;

        }
        break;

    case DFU_DNLOAD:
        if (req->type & (HOST_TO_DEVICE | TYPE_CLASS | RECIPIENT_INTF))
        {
            // wvalue is wBlockNum
            // wlength is Length
            // data is firmware
            if( dfu_status.bState == dfuIDLE )
            {
                if( req->len > 0 )
                {
                    hw_state_indicator( HW_STATE_TRANSFER );
                    dfu_status.bState = dfuDNLOAD_SYNC;
                }
                else
                {
                    dfu_status.bState  = dfuERROR;
                    dfu_status.bStatus = errNOTDONE;
                    hw_state_indicator( HW_STATE_ERROR );
                    ep_send_zlp(EP_CTRL);
                    return;
                }
            }
        	i = req->val;
            if( dfu_status.bState == dfuDNLOAD_IDLE )
            {
                if( req->len > 0 )
                {
                    dfu_status.bState = dfuDNLOAD_SYNC;
                }
                else
                {
                    if( flash_buffer_ptr > flash_buffer )
                    {
                        need_to_write = 1;
                        //flash_buffer_ptr = flash_buffer;
                    }
                    dfu_status.bState  = dfuMANIFEST_SYNC;
                    ep_send_zlp(EP_CTRL);
                    return;
                }
            }

            SI32_USB_A_clear_out_packet_ready_ep0(SI32_USB_0);

            while(pcb->fifo[EP_CTRL].len < req->len)
            {
                //ep_read(EP_CTRL);
            	i = pcb->fifo[EP_CTRL].len;
            }

            // clear the setup flag if needed
            pcb->flags &= ~(1<<SETUP_DATA_AVAIL);

            // send out a zero-length packet to ack to the host that we received
            // the new line coding
            U8* byte_buf_ptr = ( U8* )flash_buffer_ptr;
            U8 tmp_len = pcb->fifo[EP_CTRL].len;
            for(i = 0; i < tmp_len; i++)
            {
                *byte_buf_ptr = usb_buf_read(EP_CTRL);
                byte_buf_ptr++;
            }
            flash_buffer_ptr += i/4;

            if( flash_buffer_ptr == flash_buffer + BLOCK_SIZE_U32 )
            {
                // Reset buffer pointer
                //flash_buffer_ptr = flash_buffer;
                need_to_write = 1;
            }

            if( flash_buffer_ptr > flash_buffer + BLOCK_SIZE_U32)
            {
                dfu_status.bState  = dfuERROR;
                hw_state_indicator( HW_STATE_ERROR );
            }

            ep_send_zlp(EP_CTRL);
        }
        break;

    case DFU_UPLOAD:
        if (req->type & (DEVICE_TO_HOST | TYPE_CLASS | RECIPIENT_INTF))
        {
            // wvalue is zero
            // wlength is length
            // data is firmware
            // NOT SUPPORTED
            ep_set_stall(EP_CTRL);
        }
        break;

    case DFU_GETSTATUS:
        if (req->type & (DEVICE_TO_HOST | TYPE_CLASS | RECIPIENT_INTF))
        {
            if( dfu_communication_started == 0 )
                hw_state_indicator( HW_STATE_CONNECTED );

            dfu_communication_started = 1;
            // If we're still transmitting blocks
            if( dfu_status.bState == dfuDNLOAD_SYNC )
            {
                if( need_to_write == 0 )
                {
                    dfu_status.bState=dfuDNLOAD_IDLE;
                    dfu_status.bwPollTimeout0 = 0x00;
                }
                else
                {
                	dfu_status.bState=dfuDNBUSY;
                    dfu_status.bwPollTimeout0 = 0x3F;
                }
            }
            else if( dfu_status.bState == dfuDNBUSY )
            {
                if( need_to_write == 0)
                    dfu_status.bState=dfuDNLOAD_SYNC;
            }
            else if( dfu_status.bState == dfuMANIFEST_SYNC)
            {
            	dfu_status.bState=dfuMANIFEST;
                dfu_status.bwPollTimeout0 = 0xFF;
                hw_state_indicator( HW_STATE_DONE );
            }
            else if( dfu_status.bState == dfuMANIFEST &&
                     need_to_write == 0)
            {
                // Finish erasing flash
                while( flash_target < SI32_MCU_FLASH_SIZE)
                {
                    if( 0 != hw_flash_erase( flash_target, 1 ) )
                    {
                        dfu_status.bState  = dfuERROR;
                        dfu_status.bStatus = errERASE;
                        hw_state_indicator( HW_STATE_ERROR );
                    }
                    flash_target += BLOCK_SIZE_U8;
                }
                dfu_status.bState=dfuMANIFEST_WAIT_RESET;
            }

            for (i=0; i<STATUS_SZ; i++)
            {
                usb_buf_write(EP_CTRL, *((U8 *)&dfu_status + i));
            }
            ep_write(EP_CTRL);

            if( dfu_status.bState == dfuMANIFEST_WAIT_RESET )
            {
                hw_wait_ms(200);
                hw_boot_image( 1 );
            }

            if( need_to_write )
            {
                if( 0 != hw_flash_erase( flash_target, 1 ) )
                {
                    dfu_status.bState  = dfuERROR;
                    dfu_status.bStatus = errERASE;
                    hw_state_indicator( HW_STATE_ERROR );
                }
                if( 0 != hw_flash_write( flash_target, ( U32* )flash_buffer, flash_buffer_ptr - flash_buffer, 1 ) )
                {
                    dfu_status.bState  = dfuERROR;
                    dfu_status.bStatus = errVERIFY;
                    hw_state_indicator( HW_STATE_ERROR );
                }
                flash_buffer_ptr = flash_buffer;
                flash_target += BLOCK_SIZE_U8;
                need_to_write = 0;
                if( dfu_status.bState != dfuMANIFEST )
                    dfu_status.bState=dfuDNLOAD_SYNC;
            }
        }
        break;

    case DFU_CLRSTATUS:
        if (req->type & (HOST_TO_DEVICE | TYPE_CLASS | RECIPIENT_INTF))
        {
            // wvalue is zero
            // wlength is 0
            // data is  none
            if( dfu_status.bState == dfuERROR )
            {
                dfu_status.bStatus = OK;
                dfu_status.bState = dfuIDLE;
                hw_state_indicator( HW_STATE_ERROR_CLR );
            }
        }
        break;

    case DFU_GETSTATE:
        if (req->type & (DEVICE_TO_HOST | TYPE_CLASS | RECIPIENT_INTF))
        {
            // wvalue is zero
            // wlength is 1
            // data is  state
            // Transition?: No State Transition
            usb_buf_write( EP_CTRL, dfu_status.bState );
            ep_write(EP_CTRL);
        }
        break;

    case DFU_ABORT:
        if (req->type & (HOST_TO_DEVICE | TYPE_CLASS | RECIPIENT_INTF))
        {
            // wvalue is zero
            // wlength is 0
            // data is none
            if( dfu_status.bState == dfuIDLE )
            {
                dfu_status.bStatus = OK;
                dfu_status.bState = dfuIDLE;
            }
            else if ( dfu_status.bState == dfuDNLOAD_IDLE )
            {
                flash_target = FLASH_TARGET;
                if( 0 != hw_flash_erase( flash_target, 1 ) )
                {
                    dfu_status.bState  = dfuERROR;
                    dfu_status.bStatus = errERASE;
                    hw_state_indicator( HW_STATE_ERROR );
                }
                dfu_status.bStatus = OK;
                dfu_status.bState = dfuIDLE;
                ep_send_zlp(EP_CTRL);
            }
        }
        break;

    default:
        ep_set_stall(EP_CTRL);
        break;
    }
}
コード例 #14
0
ファイル: ep.c プロジェクト: pursuitxh/FreakUSB
void ep_write(U8 ep_num)
{
    U8 i, ep_size, len;
    usb_pcb_t *pcb = usb_pcb_get();

    uint32_t ControlReg = SI32_USB_A_read_ep0control(SI32_USB_0);

    ep_size = ep_size_get( ep_num );
    len = pcb->fifo[ep_num].len;

    if( len > 0 )
    {
        if( ep_num == 0 )
        {
            // Make sure we're free to write
            while( SI32_USB_A_read_ep0control(SI32_USB_0) & SI32_USB_A_EP0CONTROL_IPRDYI_MASK );

            //if( ( ongoing_write & ( 1 < ep_num ) ) == 0)
                //SI32_USB_A_clear_out_packet_ready_ep0( SI32_USB_0 );

            for (i=0; i<len; i++)
            {
                if ( i == ep_size )
                {
                    // we've filled the max packet size so break and send the data
                    //ControlReg |= SI32_USB_A_EP0CONTROL_IPRDYI_MASK;
                    //SI32_USB_0->EP0CONTROL.U32 = ControlReg;
                    ongoing_write |= ( 1 < ep_num );
                    break;
                }

                SI32_USB_A_write_ep0_fifo_u8( SI32_USB_0, usb_buf_read( ep_num ) );
            }
            ongoing_write = 0;
            ControlReg |= SI32_USB_A_EP0CONTROL_IPRDYI_MASK;
            //ControlReg |= SI32_USB_A_EP0CONTROL_DEND_MASK;
            SI32_USB_0->EP0CONTROL.U32 = ControlReg;

        }
        else
        {
            if( ep_dir_get( ep_num )  == DIR_OUT )
                return;

            // JEFF TESTING: Return immediately if our endpoint is not ready. This should never be the case
            // unless the endpoint is hung. We are not sending that much data so something must be wrong.
            // Also add a timer to the fifo_empty function at the end to eliminate endless loop on USB error.
            if( !SI32_USBEP_A_is_in_fifo_empty( usb_ep[ ep_num - 1 ] ) )
                return;
            if( SI32_USBEP_A_read_epcontrol( usb_ep[ ep_num - 1 ] ) & SI32_USBEP_A_EPCONTROL_IPRDYI_MASK )
                return;

            // Make sure we're free to write
            //while( SI32_USBEP_A_read_epcontrol( usb_ep[ ep_num - 1 ] ) & SI32_USBEP_A_EPCONTROL_IPRDYI_MASK );

            for (i=0; i<len; i++)
            {
                // check if we've reached the max packet size for the endpoint
                if ( i == ep_size )
                {
                    // we've filled the max packet size so break and send the data
                    break;
                }

                SI32_USBEP_A_write_fifo_u8( usb_ep[ ep_num - 1 ], usb_buf_read( ep_num ) );
            }

            // clearing these two will send the data out
            SI32_USBEP_A_clear_in_data_underrun( usb_ep[ ep_num - 1 ] );
            SI32_USBEP_A_set_in_packet_ready( usb_ep[ ep_num - 1 ] );
        }
    }
}
コード例 #15
0
ファイル: hw.c プロジェクト: pursuitxh/FreakUSB
void hw_init()
{
  usb_pcb_t *pcb = usb_pcb_get();
  
  SI32_CLKCTRL_0->APBCLKG0_SET = SI32_CLKCTRL_A_APBCLKG0_PLL0CEN_ENABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_PB0CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_USART0CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_USART1CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_UART0CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_UART1CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_SPI0CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_SPI1CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_SPI2CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_I2C0CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_I2C1CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_EPCA0CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_PCA0CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_PCA1CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_SSG0CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_TIMER0CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_TIMER1CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_ADC0CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_ADC1CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_CMP0CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_CMP1CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_CS0CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_AES0CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_CRC0CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_IDAC0CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_IDAC1CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_LPT0CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_I2S0CEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_USB0CEN_ENABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_EVREGCEN_DISABLED_U32 |
                                 SI32_CLKCTRL_A_APBCLKG0_FLCTRLCEN_ENABLED_U32;

  SI32_CLKCTRL_0->AHBCLKG_SET = SI32_CLKCTRL_A_AHBCLKG_RAMCEN_ENABLED_U32 |
                                SI32_CLKCTRL_A_AHBCLKG_DMACEN_DISABLED_U32 |
                                SI32_CLKCTRL_A_AHBCLKG_FLASHCEN_ENABLED_U32 |
                                SI32_CLKCTRL_A_AHBCLKG_EMIF0CEN_DISABLED_U32 |
                                SI32_CLKCTRL_A_AHBCLKG_USB0BCEN_ENABLED_U32;
                           

  SI32_WDTIMER_A_stop_counter(SI32_WDTIMER_0);

#ifdef PCB_V7
  int pcb_v7_is_defined; //Will show a compiler warning to note hardware version 
  // Setup PBHD4
  SI32_PBCFG_A_unlock_ports(SI32_PBCFG_0);
  SI32_PBHD_A_write_pblock(SI32_PBHD_4, 0x00);

  SI32_PBHD_A_select_pin0_safe_state(SI32_PBHD_4, 0x0);
  SI32_PBHD_A_select_pin1_safe_state(SI32_PBHD_4, 0x0);
  SI32_PBHD_A_select_pin2_safe_state(SI32_PBHD_4, 0x0);
  SI32_PBHD_A_select_pin3_safe_state(SI32_PBHD_4, 0x0);
  SI32_PBHD_A_select_pin4_safe_state(SI32_PBHD_4, 0x0);
  SI32_PBHD_A_select_pin5_safe_state(SI32_PBHD_4, 0x0);

  SI32_PBHD_A_enable_bias(SI32_PBHD_4);
  SI32_PBHD_A_select_normal_power_port_mode(SI32_PBHD_4);
  SI32_PBHD_A_enable_drivers(SI32_PBHD_4);

  //Setup PB4.3 LED0/1
  //Setup PB4.2 to LOW to turn on mosfets for bat charger!
  SI32_PBHD_A_set_pins_push_pull_output( SI32_PBHD_4, 0x000C );
  SI32_PBHD_A_disable_pullup_resistors( SI32_PBHD_4 );
  SI32_PBHD_A_write_pins_low( SI32_PBHD_4, 0x04 );
  SI32_PBHD_A_write_pins_high( SI32_PBHD_4, 0x08 );


  SI32_PBCFG_A_enable_crossbar_0(SI32_PBCFG_0);

  // Setup PB2
  SI32_PBSTD_A_disable_pullup_resistors( SI32_PBSTD_2 );
  // PB2.1 is wakeup
  SI32_PBSTD_A_set_pins_digital_input(SI32_PBSTD_2, 0x00000002);

  // Setup PB3 
  SI32_PBSTD_A_disable_pullup_resistors( SI32_PBSTD_3 );
  //PB3.9 is usb voltage detection
  SI32_PBSTD_A_set_pins_digital_input(SI32_PBSTD_3, 0x00000200);

#else
  int pcb_v5_is_defined; //Will show a compiler warning to note hardware version 
#endif




  /* --------------------- */
  /* Initialize USB Module */
  /* --------------------- */
  SI32_USB_A_enable_usb_oscillator(SI32_USB_0);
  SI32_USB_A_verify_clock_is_running(SI32_USB_0);
  SI32_USB_A_select_usb_clock_48mhz (SI32_USB_0);

  // Perform asynchronous reset of the USB module
  SI32_USB_A_reset_module(SI32_USB_0);
  // Wait for reset to complete
  while (SI32_USB_0->CLKSEL.RESET == SI32_USB_A_CLKSEL_RESET_SET_VALUE);

  SI32_USB_A_write_cmint (SI32_USB_0, 0x00000000);
  SI32_USB_A_write_ioint (SI32_USB_0, 0x00000000);
  SI32_USB_A_enable_ep0_interrupt (SI32_USB_0);

  // Enable Reset, Resume, Suspend interrupts
  SI32_USB_A_enable_suspend_interrupt (SI32_USB_0);
  SI32_USB_A_enable_resume_interrupt (SI32_USB_0);
  SI32_USB_A_enable_reset_interrupt (SI32_USB_0);
  //SI32_USB_A_enable_start_of_frame_interrupt (SI32_USB_0);

  // Enable Transceiver, fullspeed
  SI32_USB_A_write_tcontrol (SI32_USB_0, 0x00);
  SI32_USB_A_select_transceiver_full_speed (SI32_USB_0);
  SI32_USB_A_enable_transceiver (SI32_USB_0);
  // _SI32_USB_A_enable_internal_pull_up (SI32_USB_0);
  SI32_USB_A_enable_internal_pull_up( SI32_USB_0 );

  // Enable clock recovery, single-step mode disabled
  SI32_USB_A_enable_clock_recovery (SI32_USB_0);
  SI32_USB_A_select_clock_recovery_mode_full_speed (SI32_USB_0);
  SI32_USB_A_select_clock_recovery_normal_cal  (SI32_USB_0);

  SI32_USB_0->CMINTEPE.U32 |= (1<<16) ;
  SI32_USB_0->CMINTEPE.U32 |= 7;

  NVIC_EnableIRQ (USB0_IRQn);

  SI32_USB_A_enable_module( SI32_USB_0 );

  pcb->connected = true;
}