mirror of
https://github.com/raphnet/gc_n64_usb-v3
synced 2024-12-21 06:48:52 -05:00
Start bootloader by USB message
This commit is contained in:
parent
06bea508f1
commit
a84b70c369
2
Makefile
2
Makefile
@ -9,7 +9,7 @@ CFLAGS=-Wall -mmcu=$(CPU) -DF_CPU=16000000L -Os -DUART1_STDOUT
|
|||||||
LDFLAGS=-mmcu=$(CPU) -Wl,-Map=$(PROGNAME).map
|
LDFLAGS=-mmcu=$(CPU) -Wl,-Map=$(PROGNAME).map
|
||||||
HEXFILE=$(PROGNAME).hex
|
HEXFILE=$(PROGNAME).hex
|
||||||
|
|
||||||
OBJS=main.o n64.o gcn64_protocol.o usart1.o usb.o
|
OBJS=main.o n64.o gcn64_protocol.o usart1.o usb.o bootloader.o
|
||||||
|
|
||||||
all: $(HEXFILE)
|
all: $(HEXFILE)
|
||||||
|
|
||||||
|
17
bootloader.c
Normal file
17
bootloader.c
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#include <avr/io.h>
|
||||||
|
#include "usb.h"
|
||||||
|
|
||||||
|
void enterBootLoader(void)
|
||||||
|
{
|
||||||
|
usb_shutdown();
|
||||||
|
|
||||||
|
// AT90USB1287/1286 : 0xF000 (word address)
|
||||||
|
// ATmega32u2 : ???
|
||||||
|
asm volatile(
|
||||||
|
"cli \n"
|
||||||
|
"ldi r30, 0x00 \n" // ZL
|
||||||
|
"ldi r31, 0xF0 \n" // ZH
|
||||||
|
"ijmp");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
2
bootloader.h
Normal file
2
bootloader.h
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
void enterBootLoader(void);
|
15
dataHidReport.c
Normal file
15
dataHidReport.c
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
const uint8_t dataHidReport[] PROGMEM = {
|
||||||
|
0x06, 0x00, 0xff, // USAGE_PAGE (Generic Desktop)
|
||||||
|
0x09, 0x01, // USAGE (Vendor Usage 1)
|
||||||
|
0xa1, 0x01, // COLLECTION (Application)
|
||||||
|
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||||
|
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
|
||||||
|
0x75, 0x08, // REPORT_SIZE (8)
|
||||||
|
0x95, 0x05, // REPORT_COUNT (5)
|
||||||
|
0x09, 0x01, // USAGE (Vendor defined)
|
||||||
|
0xB1, 0x00, // FEATURE (Data,Ary,Abs)
|
||||||
|
0xc0 // END_COLLECTION
|
||||||
|
};
|
98
main.c
98
main.c
@ -7,24 +7,22 @@
|
|||||||
|
|
||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
#include "usart1.h"
|
#include "usart1.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include "gamepad.h"
|
#include "gamepad.h"
|
||||||
#include "gcn64_protocol.h"
|
#include "gcn64_protocol.h"
|
||||||
#include "n64.h"
|
#include "n64.h"
|
||||||
|
#include "bootloader.h"
|
||||||
|
|
||||||
#ifndef ARRAY_SIZE
|
uint16_t hid_get_report_main(struct usb_request *rq, const uint8_t **dat);
|
||||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
|
uint8_t hid_set_report_main(const struct usb_request *rq, const uint8_t *dat, uint16_t len);
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef LPSTR
|
uint16_t hid_get_report_data(struct usb_request *rq, const uint8_t **dat);
|
||||||
#define LPSTR(s) ((const PROGMEM wchar_t*)(s))
|
uint8_t hid_set_report_data(const struct usb_request *rq, const uint8_t *dat, uint16_t len);
|
||||||
#endif
|
|
||||||
|
|
||||||
uint16_t hid_get_report(struct usb_request *rq, const uint8_t **dat);
|
|
||||||
uint8_t hid_set_report(const struct usb_request *rq, const uint8_t *dat, uint16_t len);
|
|
||||||
|
|
||||||
#include "reportdesc.c"
|
#include "reportdesc.c"
|
||||||
|
#include "dataHidReport.c"
|
||||||
|
|
||||||
const wchar_t *const g_usb_strings[] = {
|
const wchar_t *const g_usb_strings[] = {
|
||||||
[0] = L"raphnet technologies", // 1 : Vendor
|
[0] = L"raphnet technologies", // 1 : Vendor
|
||||||
@ -37,6 +35,10 @@ struct cfg0 {
|
|||||||
struct usb_interface_descriptor interface;
|
struct usb_interface_descriptor interface;
|
||||||
struct usb_hid_descriptor hid;
|
struct usb_hid_descriptor hid;
|
||||||
struct usb_endpoint_descriptor ep1_in;
|
struct usb_endpoint_descriptor ep1_in;
|
||||||
|
|
||||||
|
struct usb_interface_descriptor interface_admin;
|
||||||
|
struct usb_hid_descriptor hid_data;
|
||||||
|
struct usb_endpoint_descriptor ep2_in;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct cfg0 cfg0 PROGMEM = {
|
static const struct cfg0 cfg0 PROGMEM = {
|
||||||
@ -44,11 +46,13 @@ static const struct cfg0 cfg0 PROGMEM = {
|
|||||||
.bLength = sizeof(struct usb_configuration_descriptor),
|
.bLength = sizeof(struct usb_configuration_descriptor),
|
||||||
.bDescriptorType = CONFIGURATION_DESCRIPTOR,
|
.bDescriptorType = CONFIGURATION_DESCRIPTOR,
|
||||||
.wTotalLength = sizeof(cfg0), // includes all descriptors returned together
|
.wTotalLength = sizeof(cfg0), // includes all descriptors returned together
|
||||||
.bNumInterfaces = 1,
|
.bNumInterfaces = 2,
|
||||||
.bConfigurationValue = 1,
|
.bConfigurationValue = 1,
|
||||||
.bmAttributes = CFG_DESC_ATTR_RESERVED, // set Self-powred and remote-wakeup here if needed.
|
.bmAttributes = CFG_DESC_ATTR_RESERVED, // set Self-powred and remote-wakeup here if needed.
|
||||||
.bMaxPower = 25, // for 50mA
|
.bMaxPower = 25, // for 50mA
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Main interface, HID
|
||||||
.interface = {
|
.interface = {
|
||||||
.bLength = sizeof(struct usb_interface_descriptor),
|
.bLength = sizeof(struct usb_interface_descriptor),
|
||||||
.bDescriptorType = INTERFACE_DESCRIPTOR,
|
.bDescriptorType = INTERFACE_DESCRIPTOR,
|
||||||
@ -76,6 +80,36 @@ static const struct cfg0 cfg0 PROGMEM = {
|
|||||||
.wMaxPacketsize = 64,
|
.wMaxPacketsize = 64,
|
||||||
.bInterval = LS_FS_INTERVAL_MS(1),
|
.bInterval = LS_FS_INTERVAL_MS(1),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Second HID interface for config and update
|
||||||
|
.interface_admin = {
|
||||||
|
.bLength = sizeof(struct usb_interface_descriptor),
|
||||||
|
.bDescriptorType = INTERFACE_DESCRIPTOR,
|
||||||
|
.bInterfaceNumber = 1,
|
||||||
|
.bAlternateSetting = 0,
|
||||||
|
.bNumEndpoints = 1,
|
||||||
|
.bInterfaceClass = USB_DEVICE_CLASS_HID,
|
||||||
|
.bInterfaceSubClass = HID_SUBCLASS_NONE,
|
||||||
|
.bInterfaceProtocol = HID_PROTOCOL_NONE,
|
||||||
|
},
|
||||||
|
.hid_data = {
|
||||||
|
.bLength = sizeof(struct usb_hid_descriptor),
|
||||||
|
.bDescriptorType = HID_DESCRIPTOR,
|
||||||
|
.bcdHid = 0x0101,
|
||||||
|
.bCountryCode = HID_COUNTRY_NOT_SUPPORTED,
|
||||||
|
.bNumDescriptors = 1, // Only a report descriptor
|
||||||
|
.bClassDescriptorType = REPORT_DESCRIPTOR,
|
||||||
|
.wClassDescriptorLength = sizeof(dataHidReport),
|
||||||
|
},
|
||||||
|
.ep2_in = {
|
||||||
|
.bLength = sizeof(struct usb_endpoint_descriptor),
|
||||||
|
.bDescriptorType = ENDPOINT_DESCRIPTOR,
|
||||||
|
.bEndpointAddress = USB_RQT_DEVICE_TO_HOST | 2, // 0x82
|
||||||
|
.bmAttributes = TRANSFER_TYPE_INT,
|
||||||
|
.wMaxPacketsize = 64,
|
||||||
|
.bInterval = LS_FS_INTERVAL_MS(1),
|
||||||
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct usb_device_descriptor device_descriptor PROGMEM = {
|
const struct usb_device_descriptor device_descriptor PROGMEM = {
|
||||||
@ -95,6 +129,8 @@ const struct usb_device_descriptor device_descriptor PROGMEM = {
|
|||||||
.iSerialNumber = 3,
|
.iSerialNumber = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** **/
|
||||||
|
|
||||||
static struct usb_parameters usb_params = {
|
static struct usb_parameters usb_params = {
|
||||||
.flags = USB_PARAM_FLAG_CONFDESC_PROGMEM |
|
.flags = USB_PARAM_FLAG_CONFDESC_PROGMEM |
|
||||||
USB_PARAM_FLAG_DEVDESC_PROGMEM |
|
USB_PARAM_FLAG_DEVDESC_PROGMEM |
|
||||||
@ -104,10 +140,22 @@ static struct usb_parameters usb_params = {
|
|||||||
.configdesc_ttllen = sizeof(cfg0),
|
.configdesc_ttllen = sizeof(cfg0),
|
||||||
.num_strings = ARRAY_SIZE(g_usb_strings),
|
.num_strings = ARRAY_SIZE(g_usb_strings),
|
||||||
.strings = g_usb_strings,
|
.strings = g_usb_strings,
|
||||||
|
|
||||||
|
.n_hid_interfaces = 2,
|
||||||
|
.hid_params = {
|
||||||
|
[0] = {
|
||||||
.reportdesc = gcn64_usbHidReportDescriptor,
|
.reportdesc = gcn64_usbHidReportDescriptor,
|
||||||
.reportdesc_len = sizeof(gcn64_usbHidReportDescriptor),
|
.reportdesc_len = sizeof(gcn64_usbHidReportDescriptor),
|
||||||
.getReport = hid_get_report,
|
.getReport = hid_get_report_main,
|
||||||
.setReport = hid_set_report,
|
.setReport = hid_set_report_main,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.reportdesc = dataHidReport,
|
||||||
|
.reportdesc_len = sizeof(dataHidReport),
|
||||||
|
.getReport = hid_get_report_data,
|
||||||
|
.setReport = hid_set_report_data,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void hwinit(void)
|
void hwinit(void)
|
||||||
@ -221,13 +269,14 @@ static void decideVibration(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t hid_get_report(struct usb_request *rq, const uint8_t **dat)
|
uint16_t hid_get_report_main(struct usb_request *rq, const uint8_t **dat)
|
||||||
{
|
{
|
||||||
uint8_t report_id = (rq->wValue & 0xff);
|
uint8_t report_id = (rq->wValue & 0xff);
|
||||||
|
|
||||||
// USB HID 1.11 section 7.2.1 Get_Report
|
// USB HID 1.11 section 7.2.1 Get_Report
|
||||||
// wValue high byte : report type
|
// wValue high byte : report type
|
||||||
// wValue low byte : report id
|
// wValue low byte : report id
|
||||||
|
// wIndex Interface
|
||||||
switch (rq->wValue >> 8)
|
switch (rq->wValue >> 8)
|
||||||
{
|
{
|
||||||
case HID_REPORT_TYPE_INPUT:
|
case HID_REPORT_TYPE_INPUT:
|
||||||
@ -290,7 +339,7 @@ uint16_t hid_get_report(struct usb_request *rq, const uint8_t **dat)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t hid_set_report(const struct usb_request *rq, const uint8_t *data, uint16_t len)
|
uint8_t hid_set_report_main(const struct usb_request *rq, const uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
if (len < 1) {
|
if (len < 1) {
|
||||||
printf_P(PSTR("shrt\n"));
|
printf_P(PSTR("shrt\n"));
|
||||||
@ -394,6 +443,27 @@ uint8_t hid_set_report(const struct usb_request *rq, const uint8_t *data, uint16
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t hid_get_report_data(struct usb_request *rq, const uint8_t **dat)
|
||||||
|
{
|
||||||
|
printf("Get data\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t hid_set_report_data(const struct usb_request *rq, const uint8_t *dat, uint16_t len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
printf("Set data %d\n", len);
|
||||||
|
|
||||||
|
for (i=0; i<len; i++) {
|
||||||
|
printf("0x%02x ", dat[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
enterBootLoader();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
Gamepad *pad = NULL;
|
Gamepad *pad = NULL;
|
||||||
|
4
usb.c
4
usb.c
@ -627,7 +627,7 @@ void usb_shutdown(void)
|
|||||||
UDIEN = 0;
|
UDIEN = 0;
|
||||||
|
|
||||||
|
|
||||||
USBCON &= (1<<USBE);
|
USBCON &= ~(1<<USBE);
|
||||||
USBCON |= (1<<FRZCLK); // initial value
|
USBCON |= (1<<FRZCLK); // initial value
|
||||||
#ifdef UHWCON
|
#ifdef UHWCON
|
||||||
UHWCON &= ~(1<<UVREGE); // Disable USB pad regulator
|
UHWCON &= ~(1<<UVREGE); // Disable USB pad regulator
|
||||||
@ -710,7 +710,7 @@ void usb_init(const struct usb_parameters *params)
|
|||||||
g_params = params;
|
g_params = params;
|
||||||
|
|
||||||
// Set some initial values
|
// Set some initial values
|
||||||
USBCON &= (1<<USBE);
|
USBCON &= ~(1<<USBE);
|
||||||
USBCON |= (1<<FRZCLK); // initial value
|
USBCON |= (1<<FRZCLK); // initial value
|
||||||
#ifdef UHWCON
|
#ifdef UHWCON
|
||||||
UHWCON |= (1<<UVREGE); // Enable USB pad regulator
|
UHWCON |= (1<<UVREGE); // Enable USB pad regulator
|
||||||
|
Loading…
Reference in New Issue
Block a user