DragonProbe/src/modeset.c

167 lines
5.7 KiB
C

// vim: set et:
#include <assert.h>
#include "alloc.h"
#include "mode.h"
extern struct mode m_01_default, m_04_sump;
// clang-format off
const struct mode* const mode_list[16] = {
NULL, // dummy 0 entry
&m_01_default, // entry 1 CANNOT be NULL!
NULL, // mode 2 (jtag scan) not implemented yet
NULL, // mode 3 (hw chip programming stuff) not implemented yet
&m_04_sump,
NULL, // terminating entry
};
// clang-format on
int mode_current_id = 1;
int mode_next_id = -1;
extern void* tusb_got[];
enum tusbgot_index {
tusbgot_hid_get_report = 0,
tusbgot_hid_set_report,
tusbgot_cdc_line_coding,
tusbgot_vendor_control_xfer,
tusbgot_hid_descriptor_report,
tusbgot_descriptor_device,
tusbgot_descriptor_configuration,
tusbgot_descriptor_string
};
#define ORDEF(a,b) ((a != NULL) ? a : b)
void modes_init(void) {
// switch to the default mode, but without doing a USB reboot thing
mode_current_id = &mode_default - mode_list;
mode_next_id = -1;
//if (!mode_default) return;
// clang-format off
#if CFG_TUD_HID > 0
tusb_got[tusbgot_hid_get_report ] =
ORDEF(mode_default->tud_hid_get_report_cb, mode_std_hid_get_report_cb);
tusb_got[tusbgot_hid_set_report ] =
ORDEF(mode_default->tud_hid_set_report_cb, mode_std_hid_set_report_cb);
#else
tusb_got[tusbgot_hid_get_report ] = NULL;
tusb_got[tusbgot_hid_set_report ] = NULL;
#endif
#if CFG_TUD_CDC > 0
tusb_got[tusbgot_cdc_line_coding ] =
ORDEF(mode_default->tud_cdc_line_coding_cb, mode_std_cdc_line_coding_cb);
#else
tusb_got[tusbgot_cdc_line_coding ] = NULL;
#endif
//#if CFG_TUD_VENDOR > 0
tusb_got[tusbgot_vendor_control_xfer] =
ORDEF(mode_default->tud_vendor_control_xfer_cb, mode_std_vendor_control_xfer_cb);
//#else
// tusb_got[tusbgot_vendor_control_xfer] = NULL;
//#endif
tusb_got[tusbgot_hid_descriptor_report ] =
ORDEF(mode_default->tud_hid_descriptor_report_cb, mode_std_hid_descriptor_report_cb);
tusb_got[tusbgot_descriptor_device ] =
ORDEF(mode_default->tud_descriptor_device_cb, mode_std_descriptor_device_cb);
tusb_got[tusbgot_descriptor_configuration] =
ORDEF(mode_default->tud_descriptor_configuration_cb, mode_std_descriptor_configuration_cb);
tusb_got[tusbgot_descriptor_string ] =
ORDEF(mode_default->tud_descriptor_string_cb, mode_std_descriptor_string_cb);
// clang-format on
}
void modes_switch(uint8_t newmode) {
for (size_t i = 0; i < 500/20; ++i) {
tud_task(); // flush ongoing stuff
sleep_ms(10);
}
if (mode_current) mode_current->leave();
// wipe all used data
m_alloc_clear();
// to force a reconfig from the device, we basically have to kill the USB
// physical connection for a while
tud_disconnect();
// maybe wait a second or so for the host to notice this
sleep_ms(500/2);
// now apply the new tusb settings
mode_current_id = (newmode >= 16 || newmode == 0) ? (-1) : newmode;
//mode_next_id = -1;
if (mode_current) {
// clang-format off
#if CFG_TUD_HID > 0
tusb_got[tusbgot_hid_get_report ] =
ORDEF(mode_current->tud_hid_get_report_cb, mode_std_hid_get_report_cb);
tusb_got[tusbgot_hid_set_report ] =
ORDEF(mode_current->tud_hid_set_report_cb, mode_std_hid_set_report_cb);
#else
tusb_got[tusbgot_hid_get_report ] = NULL;
tusb_got[tusbgot_hid_set_report ] = NULL;
#endif
#if CFG_TUD_CDC > 0
tusb_got[tusbgot_cdc_line_coding ] =
ORDEF(mode_current->tud_cdc_line_coding_cb, mode_std_cdc_line_coding_cb);
#else
tusb_got[tusbgot_cdc_line_coding ] = NULL;
#endif
//#if CFG_TUD_VENDOR > 0
tusb_got[tusbgot_vendor_control_xfer] =
ORDEF(mode_current->tud_vendor_control_xfer_cb, mode_std_vendor_control_xfer_cb);
//#else
// tusb_got[tusbgot_vendor_control_xfer] = NULL;
//#endif
tusb_got[tusbgot_hid_descriptor_report ] =
ORDEF(mode_current->tud_hid_descriptor_report_cb, mode_std_hid_descriptor_report_cb);
tusb_got[tusbgot_descriptor_device ] =
ORDEF(mode_current->tud_descriptor_device_cb, mode_std_descriptor_device_cb);
tusb_got[tusbgot_descriptor_configuration] =
ORDEF(mode_current->tud_descriptor_configuration_cb, mode_std_descriptor_configuration_cb);
tusb_got[tusbgot_descriptor_string ] =
ORDEF(mode_current->tud_descriptor_string_cb, mode_std_descriptor_string_cb);
// clang-format on
} else {
// clang-format off
#if CFG_TUD_HID > 0
tusb_got[tusbgot_hid_get_report ] = mode_std_hid_get_report_cb;
tusb_got[tusbgot_hid_set_report ] = mode_std_hid_set_report_cb;
#else
tusb_got[tusbgot_hid_get_report ] = NULL;
tusb_got[tusbgot_hid_set_report ] = NULL;
#endif
#if CFG_TUD_CDC > 0
tusb_got[tusbgot_cdc_line_coding ] = mode_std_cdc_line_coding_cb;
#else
tusb_got[tusbgot_cdc_line_coding ] = NULL;
#endif
//#if CFG_TUD_VENDOR > 0
tusb_got[tusbgot_vendor_control_xfer] = mode_std_vendor_control_xfer_cb;
//#else
// tusb_got[tusbgot_vendor_control_xfer] = NULL;
//#endif
tusb_got[tusbgot_hid_descriptor_report ] = mode_std_hid_descriptor_report_cb;
tusb_got[tusbgot_descriptor_device ] = mode_std_descriptor_device_cb;
tusb_got[tusbgot_descriptor_configuration] = mode_std_descriptor_configuration_cb;
tusb_got[tusbgot_descriptor_string ] = mode_std_descriptor_string_cb;
// clang-format on
}
// and reconnect
tud_connect();
sleep_ms(500/2);
//while (!tud_mounted()) sleep_ms(5);
if (mode_current) mode_current->enter();
}