diff --git a/Marlin/src/HAL/HAL_DUE/DebugMonitor_Due.cpp b/Marlin/src/HAL/HAL_DUE/DebugMonitor_Due.cpp index ce116678c..89206fa94 100644 --- a/Marlin/src/HAL/HAL_DUE/DebugMonitor_Due.cpp +++ b/Marlin/src/HAL/HAL_DUE/DebugMonitor_Due.cpp @@ -231,7 +231,7 @@ void HardFault_HandlerC(unsigned long *sp, unsigned long lr, unsigned long cause // Reset controller NVIC_SystemReset(); - while(1) { WDT_Restart(WDT); } + for (;;) WDT_Restart(WDT); } __attribute__((naked)) void NMI_Handler(void) { diff --git a/Marlin/src/HAL/HAL_DUE/u8g_com_HAL_DUE_shared_hw_spi.cpp b/Marlin/src/HAL/HAL_DUE/u8g_com_HAL_DUE_shared_hw_spi.cpp index 98c152143..ba7700150 100644 --- a/Marlin/src/HAL/HAL_DUE/u8g_com_HAL_DUE_shared_hw_spi.cpp +++ b/Marlin/src/HAL/HAL_DUE/u8g_com_HAL_DUE_shared_hw_spi.cpp @@ -95,7 +95,7 @@ void u8g_SetPILevel_DUE_hw_spi(u8g_t *u8g, uint8_t pin_index, uint8_t level) { } uint8_t u8g_com_HAL_DUE_shared_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { - switch(msg) { + switch (msg) { case U8G_COM_MSG_STOP: break; diff --git a/Marlin/src/HAL/HAL_LPC1768/DebugMonitor_LPC1768.cpp b/Marlin/src/HAL/HAL_LPC1768/DebugMonitor_LPC1768.cpp index ce881b7e6..998e56b6d 100644 --- a/Marlin/src/HAL/HAL_LPC1768/DebugMonitor_LPC1768.cpp +++ b/Marlin/src/HAL/HAL_LPC1768/DebugMonitor_LPC1768.cpp @@ -206,7 +206,7 @@ void HardFault_HandlerC(unsigned long *sp, unsigned long lr, unsigned long cause // Reset controller NVIC_SystemReset(); - while(1) { watchdog_init(); } + for (;;) watchdog_init(); } extern "C" { diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g/HAL_LCD_pin_routines.c b/Marlin/src/HAL/HAL_LPC1768/u8g/HAL_LCD_pin_routines.c index 48c37ed3e..4c8708495 100644 --- a/Marlin/src/HAL/HAL_LPC1768/u8g/HAL_LCD_pin_routines.c +++ b/Marlin/src/HAL/HAL_LPC1768/u8g/HAL_LCD_pin_routines.c @@ -45,12 +45,11 @@ #define OUTPUT 1 #define INPUT_PULLUP 2 - uint8_t LPC1768_PIN_PORT(const uint8_t pin); uint8_t LPC1768_PIN_PIN(const uint8_t pin); #ifdef __cplusplus - extern "C" { + extern "C" { #endif // I/O functions @@ -63,22 +62,21 @@ void pinMode_LCD(uint8_t pin, uint8_t mode) { PINSEL_FUNC_0, PINSEL_PINMODE_TRISTATE, PINSEL_PINMODE_NORMAL }; - switch(mode) { - case INPUT: - LPC_GPIO(LPC1768_PIN_PORT(pin))->FIODIR &= ~LPC_PIN(LPC1768_PIN_PIN(pin)); - PINSEL_ConfigPin(&config); - break; - case OUTPUT: - LPC_GPIO(LPC1768_PIN_PORT(pin))->FIODIR |= LPC_PIN(LPC1768_PIN_PIN(pin)); - PINSEL_ConfigPin(&config); - break; - case INPUT_PULLUP: - LPC_GPIO(LPC1768_PIN_PORT(pin))->FIODIR &= ~LPC_PIN(LPC1768_PIN_PIN(pin)); - config.Pinmode = PINSEL_PINMODE_PULLUP; - PINSEL_ConfigPin(&config); - break; - default: - break; + switch (mode) { + case INPUT: + LPC_GPIO(LPC1768_PIN_PORT(pin))->FIODIR &= ~LPC_PIN(LPC1768_PIN_PIN(pin)); + PINSEL_ConfigPin(&config); + break; + case OUTPUT: + LPC_GPIO(LPC1768_PIN_PORT(pin))->FIODIR |= LPC_PIN(LPC1768_PIN_PIN(pin)); + PINSEL_ConfigPin(&config); + break; + case INPUT_PULLUP: + LPC_GPIO(LPC1768_PIN_PORT(pin))->FIODIR &= ~LPC_PIN(LPC1768_PIN_PIN(pin)); + config.Pinmode = PINSEL_PINMODE_PULLUP; + PINSEL_ConfigPin(&config); + break; + default: break; } } @@ -105,7 +103,6 @@ uint8_t u8g_GetPinLevel(uint8_t pin) { return (uint32_t)LPC_GPIO(LPC1768_PIN_PORT(pin))->FIOPIN & LPC_PIN(LPC1768_PIN_PIN(pin)) ? 1 : 0; } - #ifdef __cplusplus } #endif diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp b/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp index 65bd4b407..4495e7f7e 100644 --- a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp +++ b/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp @@ -95,9 +95,8 @@ uint8_t u8g_com_ssd_I2C_start_sequence(u8g_t *u8g) { if (u8g->pin_list[U8G_PI_SET_A0] == 0) return 1; /* setup bus, might be a repeated start */ - if (u8g_i2c_start(I2C_SLA) == 0) - return 0; - if (u8g->pin_list[U8G_PI_A0_STATE] == 0 ) { + if (u8g_i2c_start(I2C_SLA) == 0) return 0; + if (u8g->pin_list[U8G_PI_A0_STATE] == 0) { if (u8g_i2c_send_byte(I2C_CMD_MODE) == 0) return 0; } else if (u8g_i2c_send_byte(I2C_DATA_MODE) == 0) @@ -108,7 +107,7 @@ uint8_t u8g_com_ssd_I2C_start_sequence(u8g_t *u8g) { } uint8_t u8g_com_HAL_LPC1768_ssd_hw_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { - switch(msg) { + switch (msg) { case U8G_COM_MSG_INIT: //u8g_com_arduino_digital_write(u8g, U8G_PI_SCL, HIGH); //u8g_com_arduino_digital_write(u8g, U8G_PI_SDA, HIGH); diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp b/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp index 4668954ad..3a9ffa8e2 100644 --- a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp +++ b/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp @@ -91,7 +91,7 @@ static void u8g_com_LPC1768_st7920_write_byte_hw_spi(uint8_t rs, uint8_t val) { } uint8_t u8g_com_HAL_LPC1768_ST7920_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { - switch(msg) { + switch (msg) { case U8G_COM_MSG_INIT: u8g_SetPILevel(u8g, U8G_PI_CS, 0); u8g_SetPIOutput(u8g, U8G_PI_CS); diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp b/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp index 01da8dfde..ec0ddc90f 100644 --- a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp +++ b/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp @@ -89,10 +89,8 @@ static void u8g_com_LPC1768_st7920_write_byte_sw_spi(uint8_t rs, uint8_t val) { swSpiTransfer(val << 4, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL); } -uint8_t u8g_com_HAL_LPC1768_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) -{ - switch(msg) - { +uint8_t u8g_com_HAL_LPC1768_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { + switch (msg) { case U8G_COM_MSG_INIT: SCK_pin_ST7920_HAL = u8g->pin_list[U8G_PI_SCK]; MOSI_pin_ST7920_HAL_HAL = u8g->pin_list[U8G_PI_MOSI]; diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp b/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp index e865c3de7..1419a74f4 100644 --- a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp +++ b/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp @@ -72,7 +72,7 @@ static void u8g_sw_spi_HAL_LPC1768_shift_out(uint8_t dataPin, uint8_t clockPin, } uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { - switch(msg) { + switch (msg) { case U8G_COM_MSG_INIT: u8g_SetPIOutput(u8g, U8G_PI_SCK); u8g_SetPIOutput(u8g, U8G_PI_MOSI); diff --git a/Marlin/src/HAL/HAL_STM32F1/u8g_com_stm32duino_fsmc.cpp b/Marlin/src/HAL/HAL_STM32F1/u8g_com_stm32duino_fsmc.cpp index d9c01cb5c..18cd7c10f 100644 --- a/Marlin/src/HAL/HAL_STM32F1/u8g_com_stm32duino_fsmc.cpp +++ b/Marlin/src/HAL/HAL_STM32F1/u8g_com_stm32duino_fsmc.cpp @@ -58,7 +58,7 @@ uint8_t u8g_com_stm32duino_fsmc_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, voi static uint8_t isCommand; - switch(msg) { + switch (msg) { case U8G_COM_MSG_STOP: break; case U8G_COM_MSG_INIT: @@ -154,7 +154,7 @@ void LCD_IO_Init(uint8_t cs, uint8_t rs) { if (fsmcInit) return; fsmcInit = 1; - switch(cs) { + switch (cs) { case FSMC_CS_NE1: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION1; break; case FSMC_CS_NE2: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION2; break; case FSMC_CS_NE3: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION3; break; @@ -164,7 +164,7 @@ void LCD_IO_Init(uint8_t cs, uint8_t rs) { #define _ORADDR(N) controllerAddress |= (_BV32(N) - 2) - switch(rs) { + switch (rs) { case FSMC_RS_A0: _ORADDR( 1); break; case FSMC_RS_A1: _ORADDR( 2); break; case FSMC_RS_A2: _ORADDR( 3); break; diff --git a/Marlin/src/HAL/HAL_TEENSY31_32/HAL_timers_Teensy.cpp b/Marlin/src/HAL/HAL_TEENSY31_32/HAL_timers_Teensy.cpp index 298da6a42..fccba9e6a 100644 --- a/Marlin/src/HAL/HAL_TEENSY31_32/HAL_timers_Teensy.cpp +++ b/Marlin/src/HAL/HAL_TEENSY31_32/HAL_timers_Teensy.cpp @@ -71,7 +71,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { } void HAL_timer_enable_interrupt(const uint8_t timer_num) { - switch(timer_num) { + switch (timer_num) { case 0: NVIC_ENABLE_IRQ(IRQ_FTM0); break; case 1: NVIC_ENABLE_IRQ(IRQ_FTM1); break; } @@ -98,7 +98,7 @@ bool HAL_timer_interrupt_enabled(const uint8_t timer_num) { } void HAL_timer_isr_prologue(const uint8_t timer_num) { - switch(timer_num) { + switch (timer_num) { case 0: FTM0_CNT = 0x0000; FTM0_SC &= ~FTM_SC_TOF; // Clear FTM Overflow flag diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/HAL_timers_Teensy.cpp b/Marlin/src/HAL/HAL_TEENSY35_36/HAL_timers_Teensy.cpp index b26e1a3d1..471d823da 100644 --- a/Marlin/src/HAL/HAL_TEENSY35_36/HAL_timers_Teensy.cpp +++ b/Marlin/src/HAL/HAL_TEENSY35_36/HAL_timers_Teensy.cpp @@ -72,7 +72,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { } void HAL_timer_enable_interrupt(const uint8_t timer_num) { - switch(timer_num) { + switch (timer_num) { case 0: NVIC_ENABLE_IRQ(IRQ_FTM0); break; case 1: NVIC_ENABLE_IRQ(IRQ_FTM1); break; } @@ -99,7 +99,7 @@ bool HAL_timer_interrupt_enabled(const uint8_t timer_num) { } void HAL_timer_isr_prologue(const uint8_t timer_num) { - switch(timer_num) { + switch (timer_num) { case 0: FTM0_CNT = 0x0000; FTM0_SC &= ~FTM_SC_TOF; // Clear FTM Overflow flag diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/pinsDebug.h b/Marlin/src/HAL/HAL_TEENSY35_36/pinsDebug.h index a739121e7..cb472aff0 100644 --- a/Marlin/src/HAL/HAL_TEENSY35_36/pinsDebug.h +++ b/Marlin/src/HAL/HAL_TEENSY35_36/pinsDebug.h @@ -76,7 +76,7 @@ void HAL_analog_pin_state(char buffer[], int8_t pin) { */ bool HAL_pwm_status(int8_t pin) { char buffer[20]; // for the sprintf statements - switch(pin) { + switch (pin) { FTM_CASE(0,0); FTM_CASE(0,1); FTM_CASE(0,2); diff --git a/Marlin/src/HAL/shared/backtrace/unwarm.h b/Marlin/src/HAL/shared/backtrace/unwarm.h index 9594ed95d..3128e354c 100644 --- a/Marlin/src/HAL/shared/backtrace/unwarm.h +++ b/Marlin/src/HAL/shared/backtrace/unwarm.h @@ -103,7 +103,7 @@ typedef struct { * Macros **************************************************************************/ -#define M_IsOriginValid(v) (((v) & 0x7F) ? true : false) +#define M_IsOriginValid(v) !!((v) & 0x7F) #define M_Origin2Str(v) ((v) ? "VALID" : "INVALID") #ifdef UNW_DEBUG diff --git a/Marlin/src/HAL/shared/backtrace/unwarm_arm.cpp b/Marlin/src/HAL/shared/backtrace/unwarm_arm.cpp index be43b2239..3c9c5aaee 100644 --- a/Marlin/src/HAL/shared/backtrace/unwarm_arm.cpp +++ b/Marlin/src/HAL/shared/backtrace/unwarm_arm.cpp @@ -32,23 +32,17 @@ * \retval false This is not a data-processing instruction, */ static bool isDataProc(uint32_t instr) { - uint8_t opcode = (instr & 0x01E00000) >> 21; - bool S = (instr & 0x00100000) ? true : false; - - if ((instr & 0xFC000000) != 0xE0000000) { - return false; - } - else if (!S && opcode >= 8 && opcode <= 11) { - /* TST, TEQ, CMP and CMN all require S to be set */ - return false; - } - else - return true; + if ((instr & 0xFC000000) != 0xE0000000) return false; + + /* TST, TEQ, CMP and CMN all require S to be set */ + bool S = !!(instr & 0x00100000); + if (!S && opcode >= 8 && opcode <= 11) return false; + + return true; } UnwResult UnwStartArm(UnwState * const state) { - bool found = false; uint16_t t = UNW_MAX_INSTR_COUNT; @@ -56,9 +50,8 @@ UnwResult UnwStartArm(UnwState * const state) { uint32_t instr; /* Attempt to read the instruction */ - if (!state->cb->readW(state->regData[15].v, &instr)) { + if (!state->cb->readW(state->regData[15].v, &instr)) return UNWIND_IREAD_W_FAIL; - } UnwPrintd4("A %x %x %08x:", state->regData[13].v, state->regData[15].v, instr); @@ -103,31 +96,20 @@ UnwResult UnwStartArm(UnwState * const state) { } /* Determine the return mode */ - if (state->regData[rn].v & 0x1) { - - /* Branching to THUMB */ + if (state->regData[rn].v & 0x1) /* Branching to THUMB */ return UnwStartThumb(state); - } - else { - - /* Branch to ARM */ - /* Account for the auto-increment which isn't needed */ - state->regData[15].v -= 4; - } + /* Branch to ARM */ + /* Account for the auto-increment which isn't needed */ + state->regData[15].v -= 4; } /* Branch */ else if ((instr & 0xFF000000) == 0xEA000000) { - int32_t offset = (instr & 0x00FFFFFF); - - /* Shift value */ - offset = offset << 2; + int32_t offset = (instr & 0x00FFFFFF) << 2; /* Sign extend if needed */ - if (offset & 0x02000000) { - offset |= 0xFC000000; - } + if (offset & 0x02000000) offset |= 0xFC000000; UnwPrintd2("B %d\n", offset); @@ -142,11 +124,12 @@ UnwResult UnwStartArm(UnwState * const state) { /* MRS */ else if ((instr & 0xFFBF0FFF) == 0xE10F0000) { -#ifdef UNW_DEBUG - bool R = (instr & 0x00400000) ? true : false; -#endif + #ifdef UNW_DEBUG + const bool R = !!(instr & 0x00400000); + #else + constexpr bool R = false; + #endif uint8_t rd = (instr & 0x0000F000) >> 12; - UnwPrintd4("MRS r%d,%s\t; r%d invalidated", rd, R ? "SPSR" : "CPSR", rd); /* Status registers untracked */ @@ -154,11 +137,10 @@ UnwResult UnwStartArm(UnwState * const state) { } /* MSR */ else if ((instr & 0xFFB0F000) == 0xE120F000) { -#ifdef UNW_DEBUG - bool R = (instr & 0x00400000) ? true : false; + #ifdef UNW_DEBUG + UnwPrintd2("MSR %s_?, ???", (instr & 0x00400000) ? "SPSR" : "CPSR"); + #endif - UnwPrintd2("MSR %s_?, ???", R ? "SPSR" : "CPSR"); -#endif /* Status registers untracked. * Potentially this could change processor mode and switch * banked registers r8-r14. Most likely is that r13 (sp) will @@ -170,18 +152,18 @@ UnwResult UnwStartArm(UnwState * const state) { } /* Data processing */ else if (isDataProc(instr)) { - bool I = (instr & 0x02000000) ? true : false; + bool I = !!(instr & 0x02000000); uint8_t opcode = (instr & 0x01E00000) >> 21; -#ifdef UNW_DEBUG - bool S = (instr & 0x00100000) ? true : false; -#endif + #ifdef UNW_DEBUG + bool S = !!(instr & 0x00100000); + #endif uint8_t rn = (instr & 0x000F0000) >> 16; uint8_t rd = (instr & 0x0000F000) >> 12; uint16_t operand2 = (instr & 0x00000FFF); uint32_t op2val; int op2origin; - switch(opcode) { + switch (opcode) { case 0: UnwPrintd4("AND%s r%d,r%d,", S ? "S" : "", rd, rn); break; case 1: UnwPrintd4("EOR%s r%d,r%d,", S ? "S" : "", rd, rn); break; case 2: UnwPrintd4("SUB%s r%d,r%d,", S ? "S" : "", rd, rn); break; @@ -217,26 +199,23 @@ UnwResult UnwStartArm(UnwState * const state) { /* Register and shift */ uint8_t rm = (operand2 & 0x000F); - uint8_t regShift = (operand2 & 0x0010) ? true : false; + uint8_t regShift = !!(operand2 & 0x0010); uint8_t shiftType = (operand2 & 0x0060) >> 5; uint32_t shiftDist; -#ifdef UNW_DEBUG - const char * const shiftMnu[4] = { "LSL", "LSR", "ASR", "ROR" }; -#endif + #ifdef UNW_DEBUG + const char * const shiftMnu[4] = { "LSL", "LSR", "ASR", "ROR" }; + #endif UnwPrintd2("r%d ", rm); /* Get the shift distance */ if (regShift) { - uint8_t rs = (operand2 & 0x0F00) >> 8; if (operand2 & 0x00800) { - UnwPrintd1("\nError: Bit should be zero\n"); return UNWIND_ILLEGAL_INSTR; } else if (rs == 15) { - UnwPrintd1("\nError: Cannot use R15 with register shift\n"); return UNWIND_ILLEGAL_INSTR; } @@ -250,46 +229,33 @@ UnwResult UnwStartArm(UnwState * const state) { else { shiftDist = (operand2 & 0x0F80) >> 7; op2origin = REG_VAL_FROM_CONST; - - if (shiftDist) { - UnwPrintd3("%s #%d", shiftMnu[shiftType], shiftDist); - } + if (shiftDist) UnwPrintd3("%s #%d", shiftMnu[shiftType], shiftDist); UnwPrintd3("\t; r%d %s", rm, M_Origin2Str(state->regData[rm].o)); } /* Apply the shift type to the source register */ - switch(shiftType) { + switch (shiftType) { case 0: /* logical left */ op2val = state->regData[rm].v << shiftDist; break; case 1: /* logical right */ - if (!regShift && shiftDist == 0) { - shiftDist = 32; - } - + if (!regShift && shiftDist == 0) shiftDist = 32; op2val = state->regData[rm].v >> shiftDist; break; case 2: /* arithmetic right */ - if (!regShift && shiftDist == 0) { - shiftDist = 32; - } + if (!regShift && shiftDist == 0) shiftDist = 32; if (state->regData[rm].v & 0x80000000) { - /* Register shifts maybe greater than 32 */ - if (shiftDist >= 32) { + if (shiftDist >= 32) op2val = 0xFFFFFFFF; - } - else { - op2val = state->regData[rm].v >> shiftDist; - op2val |= 0xFFFFFFFF << (32 - shiftDist); - } + else + op2val = (state->regData[rm].v >> shiftDist) | (0xFFFFFFFF << (32 - shiftDist)); } - else { + else op2val = state->regData[rm].v >> shiftDist; - } break; case 3: /* rotate right */ @@ -317,19 +283,14 @@ UnwResult UnwStartArm(UnwState * const state) { } /* Decide the data origin */ - if (M_IsOriginValid(op2origin) && - M_IsOriginValid(state->regData[rm].o)) { - - op2origin = state->regData[rm].o; - op2origin |= REG_VAL_ARITHMETIC; - } - else { + if (M_IsOriginValid(op2origin) && M_IsOriginValid(state->regData[rm].o)) + op2origin = REG_VAL_ARITHMETIC | state->regData[rm].o; + else op2origin = REG_VAL_INVALID; - } } /* Propagate register validity */ - switch(opcode) { + switch (opcode) { case 0: /* AND: Rd := Op1 AND Op2 */ case 1: /* EOR: Rd := Op1 EOR Op2 */ case 2: /* SUB: Rd:= Op1 - Op2 */ @@ -374,14 +335,11 @@ UnwResult UnwStartArm(UnwState * const state) { * to specify the shift amount the PC will be 12 bytes * ahead. */ - if (!I && (operand2 & 0x0010)) - state->regData[rn].v += 12; - else - state->regData[rn].v += 8; + state->regData[rn].v += ((!I && (operand2 & 0x0010)) ? 12 : 8); } /* Compute values */ - switch(opcode) { + switch (opcode) { case 0: /* AND: Rd := Op1 AND Op2 */ state->regData[rd].v = state->regData[rn].v & op2val; break; @@ -429,12 +387,8 @@ UnwResult UnwStartArm(UnwState * const state) { } /* Remove the prefetch offset from the PC */ - if (rd != 15 && rn == 15) { - if (!I && (operand2 & 0x0010)) - state->regData[rn].v -= 12; - else - state->regData[rn].v -= 8; - } + if (rd != 15 && rn == 15) + state->regData[rn].v -= ((!I && (operand2 & 0x0010)) ? 12 : 8); } /* Block Data Transfer @@ -442,26 +396,25 @@ UnwResult UnwStartArm(UnwState * const state) { */ else if ((instr & 0xFE000000) == 0xE8000000) { - bool P = (instr & 0x01000000) ? true : false; - bool U = (instr & 0x00800000) ? true : false; - bool S = (instr & 0x00400000) ? true : false; - bool W = (instr & 0x00200000) ? true : false; - bool L = (instr & 0x00100000) ? true : false; + bool P = !!(instr & 0x01000000), + U = !!(instr & 0x00800000), + S = !!(instr & 0x00400000), + W = !!(instr & 0x00200000), + L = !!(instr & 0x00100000); uint16_t baseReg = (instr & 0x000F0000) >> 16; uint16_t regList = (instr & 0x0000FFFF); uint32_t addr = state->regData[baseReg].v; bool addrValid = M_IsOriginValid(state->regData[baseReg].o); int8_t r; -#ifdef UNW_DEBUG - /* Display the instruction */ - if (L) { - UnwPrintd6("LDM%c%c r%d%s, {reglist}%s\n", P ? 'E' : 'F', U ? 'D' : 'A', baseReg, W ? "!" : "", S ? "^" : ""); - } - else { - UnwPrintd6("STM%c%c r%d%s, {reglist}%s\n", !P ? 'E' : 'F', !U ? 'D' : 'A', baseReg, W ? "!" : "", S ? "^" : ""); - } -#endif + #ifdef UNW_DEBUG + /* Display the instruction */ + if (L) + UnwPrintd6("LDM%c%c r%d%s, {reglist}%s\n", P ? 'E' : 'F', U ? 'D' : 'A', baseReg, W ? "!" : "", S ? "^" : ""); + else + UnwPrintd6("STM%c%c r%d%s, {reglist}%s\n", !P ? 'E' : 'F', !U ? 'D' : 'A', baseReg, W ? "!" : "", S ? "^" : ""); + #endif + /* S indicates that banked registers (untracked) are used, unless * this is a load including the PC when the S-bit indicates that * that CPSR is loaded from SPSR (also untracked, but ignored). @@ -489,44 +442,35 @@ UnwResult UnwStartArm(UnwState * const state) { /* Check if the register is to be transferred */ if (regList & (0x01 << r)) { - if (P) - addr += U ? 4 : -4; + if (P) addr += U ? 4 : -4; if (L) { if (addrValid) { - if (!UnwMemReadRegister(state, addr, &state->regData[r])) { + if (!UnwMemReadRegister(state, addr, &state->regData[r])) return UNWIND_DREAD_W_FAIL; - } /* Update the origin if read via the stack pointer */ - if (M_IsOriginValid(state->regData[r].o) && baseReg == 13) { + if (M_IsOriginValid(state->regData[r].o) && baseReg == 13) state->regData[r].o = REG_VAL_FROM_STACK; - } UnwPrintd5(" R%d = 0x%08x\t; r%d %s\n",r,state->regData[r].v,r, M_Origin2Str(state->regData[r].o)); } else { - /* Invalidate the register as the base reg was invalid */ state->regData[r].o = REG_VAL_INVALID; - UnwPrintd2(" R%d = ???\n", r); } } else { - if (addrValid) { - if (!UnwMemWriteRegister(state, state->regData[13].v, &state->regData[r])) { - return UNWIND_DWRITE_W_FAIL; - } - } + if (addrValid && !UnwMemWriteRegister(state, state->regData[13].v, &state->regData[r])) + return UNWIND_DWRITE_W_FAIL; UnwPrintd2(" R%d = 0x%08x\n", r); } - if (!P) - addr += U ? 4 : -4; + if (!P) addr += U ? 4 : -4; } /* Check the next register */ @@ -535,8 +479,7 @@ UnwResult UnwStartArm(UnwState * const state) { } while (r >= 0 && r <= 15); /* Check the writeback bit */ - if (W) - state->regData[baseReg].v = addr; + if (W) state->regData[baseReg].v = addr; /* Check if the PC was loaded */ if (L && (regList & (0x01 << 15))) { @@ -547,9 +490,8 @@ UnwResult UnwStartArm(UnwState * const state) { } else { /* Store the return address */ - if (!UnwReportRetAddr(state, state->regData[15].v)) { + if (!UnwReportRetAddr(state, state->regData[15].v)) return UNWIND_TRUNCATED; - } UnwPrintd2(" Return PC=0x%x", state->regData[15].v); @@ -585,9 +527,7 @@ UnwResult UnwStartArm(UnwState * const state) { /* Garbage collect the memory hash (used only for the stack) */ UnwMemHashGC(state); - t--; - if (t == 0) - return UNWIND_EXHAUSTED; + if (--t == 0) return UNWIND_EXHAUSTED; } while (!found); diff --git a/Marlin/src/HAL/shared/backtrace/unwarm_thumb.cpp b/Marlin/src/HAL/shared/backtrace/unwarm_thumb.cpp index 29efb1309..d5449f863 100644 --- a/Marlin/src/HAL/shared/backtrace/unwarm_thumb.cpp +++ b/Marlin/src/HAL/shared/backtrace/unwarm_thumb.cpp @@ -25,17 +25,11 @@ * \param value The value to sign extend. * \return The signed-11 bit value stored in a 16bit data type. */ -static int32_t signExtend11(uint16_t value) { - - if(value & 0x400) { - value |= 0xFFFFF800; - } - - return value; +static int32_t signExtend11(const uint16_t value) { + return (value & 0x400) ? value | 0xFFFFF800 : value; } UnwResult UnwStartThumb(UnwState * const state) { - bool found = false; uint16_t t = UNW_MAX_INSTR_COUNT; uint32_t lastJumpAddr = 0; // Last JUMP address, to try to detect infinite loops @@ -45,20 +39,19 @@ UnwResult UnwStartThumb(UnwState * const state) { uint16_t instr; /* Attempt to read the instruction */ - if(!state->cb->readH(state->regData[15].v & (~0x1), &instr)) { + if (!state->cb->readH(state->regData[15].v & (~0x1), &instr)) return UNWIND_IREAD_H_FAIL; - } UnwPrintd4("T %x %x %04x:", state->regData[13].v, state->regData[15].v, instr); /* Check that the PC is still on Thumb alignment */ - if(!(state->regData[15].v & 0x1)) { + if (!(state->regData[15].v & 0x1)) { UnwPrintd1("\nError: PC misalignment\n"); return UNWIND_INCONSISTENT; } /* Check that the SP and PC have not been invalidated */ - if(!M_IsOriginValid(state->regData[13].o) || !M_IsOriginValid(state->regData[15].o)) { + if (!M_IsOriginValid(state->regData[13].o) || !M_IsOriginValid(state->regData[15].o)) { UnwPrintd1("\nError: PC or SP invalidated\n"); return UNWIND_INCONSISTENT; } @@ -73,9 +66,8 @@ UnwResult UnwStartThumb(UnwState * const state) { state->regData[15].v += 2; /* Attempt to read the 2nd part of the instruction */ - if(!state->cb->readH(state->regData[15].v & (~0x1), &instr2)) { + if (!state->cb->readH(state->regData[15].v & (~0x1), &instr2)) return UNWIND_IREAD_H_FAIL; - } UnwPrintd3(" %x %04x:", state->regData[15].v, instr2); @@ -84,26 +76,25 @@ UnwResult UnwStartThumb(UnwState * const state) { * PUSH and POP */ if ((instr & 0xFE6F) == 0xE82D) { - bool L = (instr & 0x10) ? true : false; + bool L = !!(instr & 0x10); uint16_t rList = instr2; - if(L) { + if (L) { uint8_t r; /* Load from memory: POP */ UnwPrintd1("POP {Rlist}\n"); /* Load registers from stack */ - for(r = 0; r < 16; r++) { - if(rList & (0x1 << r)) { + for (r = 0; r < 16; r++) { + if (rList & (0x1 << r)) { /* Read the word */ - if(!UnwMemReadRegister(state, state->regData[13].v, &state->regData[r])) { + if (!UnwMemReadRegister(state, state->regData[13].v, &state->regData[r])) return UNWIND_DREAD_W_FAIL; - } /* Alter the origin to be from the stack if it was valid */ - if(M_IsOriginValid(state->regData[r].o)) { + if (M_IsOriginValid(state->regData[r].o)) { state->regData[r].o = REG_VAL_FROM_STACK; @@ -114,7 +105,7 @@ UnwResult UnwStartThumb(UnwState * const state) { * the caller was from Thumb. This would allow return * by BX for interworking APCS. */ - if((state->regData[15].v & 0x1) == 0) { + if ((state->regData[15].v & 0x1) == 0) { UnwPrintd2("Warning: Return address not to Thumb: 0x%08x\n", state->regData[15].v); /* Pop into the PC will not switch mode */ @@ -122,9 +113,8 @@ UnwResult UnwStartThumb(UnwState * const state) { } /* Store the return address */ - if(!UnwReportRetAddr(state, state->regData[15].v)) { + if (!UnwReportRetAddr(state, state->regData[15].v)) return UNWIND_TRUNCATED; - } /* Now have the return address */ UnwPrintd2(" Return PC=%x\n", state->regData[15].v); @@ -155,15 +145,14 @@ UnwResult UnwStartThumb(UnwState * const state) { /* Store to memory: PUSH */ UnwPrintd1("PUSH {Rlist}"); - for(r = 15; r >= 0; r--) { - if(rList & (0x1 << r)) { + for (r = 15; r >= 0; r--) { + if (rList & (0x1 << r)) { UnwPrintd4("\n r%d = 0x%08x\t; %s", r, state->regData[r].v, M_Origin2Str(state->regData[r].o)); state->regData[13].v -= 4; - if(!UnwMemWriteRegister(state, state->regData[13].v, &state->regData[r])) { + if (!UnwMemWriteRegister(state, state->regData[13].v, &state->regData[r])) return UNWIND_DWRITE_W_FAIL; - } } } } @@ -180,9 +169,8 @@ UnwResult UnwStartThumb(UnwState * const state) { state->regData[13].v -= 4; - if(!UnwMemWriteRegister(state, state->regData[13].v, &state->regData[r])) { + if (!UnwMemWriteRegister(state, state->regData[13].v, &state->regData[r])) return UNWIND_DWRITE_W_FAIL; - } } /* * POP register @@ -194,12 +182,11 @@ UnwResult UnwStartThumb(UnwState * const state) { UnwPrintd2("POP {R%d}\n", r); /* Read the word */ - if(!UnwMemReadRegister(state, state->regData[13].v, &state->regData[r])) { + if (!UnwMemReadRegister(state, state->regData[13].v, &state->regData[r])) return UNWIND_DREAD_W_FAIL; - } /* Alter the origin to be from the stack if it was valid */ - if(M_IsOriginValid(state->regData[r].o)) { + if (M_IsOriginValid(state->regData[r].o)) { state->regData[r].o = REG_VAL_FROM_STACK; @@ -210,7 +197,7 @@ UnwResult UnwStartThumb(UnwState * const state) { * the caller was from Thumb. This would allow return * by BX for interworking APCS. */ - if((state->regData[15].v & 0x1) == 0) { + if ((state->regData[15].v & 0x1) == 0) { UnwPrintd2("Warning: Return address not to Thumb: 0x%08x\n", state->regData[15].v); /* Pop into the PC will not switch mode */ @@ -218,9 +205,8 @@ UnwResult UnwStartThumb(UnwState * const state) { } /* Store the return address */ - if(!UnwReportRetAddr(state, state->regData[15].v)) { + if (!UnwReportRetAddr(state, state->regData[15].v)) return UNWIND_TRUNCATED; - } /* Now have the return address */ UnwPrintd2(" Return PC=%x\n", state->regData[15].v); @@ -255,7 +241,7 @@ UnwResult UnwStartThumb(UnwState * const state) { * the switch clauses */ uint8_t rn = instr & 0xF; - bool H = (instr2 & 0x10) ? true : false; + bool H = !!(instr2 & 0x10); UnwPrintd5("TB%c [r%d,r%d%s]\n", H ? 'H' : 'B', rn, (instr2 & 0xF), H ? ",LSL #1" : ""); @@ -263,15 +249,14 @@ UnwResult UnwStartThumb(UnwState * const state) { if (rn == 15) { if (H) { uint16_t rv; - if(!state->cb->readH((state->regData[15].v & (~1)) + 2, &rv)) { + if (!state->cb->readH((state->regData[15].v & (~1)) + 2, &rv)) return UNWIND_DREAD_H_FAIL; - } state->regData[15].v += rv * 2; - } else { + } + else { uint8_t rv; - if(!state->cb->readB((state->regData[15].v & (~1)) + 2, &rv)) { + if (!state->cb->readB((state->regData[15].v & (~1)) + 2, &rv)) return UNWIND_DREAD_B_FAIL; - } state->regData[15].v += rv * 2; } } @@ -355,12 +340,11 @@ UnwResult UnwStartThumb(UnwState * const state) { UnwPrintd2(" Return PC=%x", state->regData[15].v); /* Report the return address, including mode bit */ - if(!UnwReportRetAddr(state, state->regData[15].v)) { + if (!UnwReportRetAddr(state, state->regData[15].v)) return UNWIND_TRUNCATED; - } /* Determine the new mode */ - if(state->regData[15].v & 0x1) { + if (state->regData[15].v & 0x1) { /* Branching to THUMB */ /* Account for the auto-increment which isn't needed */ @@ -411,10 +395,10 @@ UnwResult UnwStartThumb(UnwState * const state) { * PC-relative load * LDR Rd,[PC, #+/-imm] */ - else if((instr & 0xFF7F) == 0xF85F) { + else if ((instr & 0xFF7F) == 0xF85F) { uint8_t rt = (instr2 & 0xF000) >> 12; uint8_t imm12 = (instr2 & 0x0FFF); - bool A = (instr & 0x80) ? true : false; + bool A = !!(instr & 0x80); uint32_t address; /* Compute load address, adding a word to account for prefetch */ @@ -424,9 +408,8 @@ UnwResult UnwStartThumb(UnwState * const state) { UnwPrintd4("LDR r%d,[PC #%c0x%08x]", rt, A?'+':'-', address); - if(!UnwMemReadRegister(state, address, &state->regData[rt])) { + if (!UnwMemReadRegister(state, address, &state->regData[rt])) return UNWIND_DREAD_W_FAIL; - } } /* * LDR immediate. @@ -441,11 +424,11 @@ UnwResult UnwStartThumb(UnwState * const state) { /* If destination is PC and we don't know the source value, then fail */ if (!M_IsOriginValid(state->regData[rn].o)) { state->regData[rt].o = state->regData[rn].o; - } else { + } + else { uint32_t address = state->regData[rn].v + imm12; - if(!UnwMemReadRegister(state, address, &state->regData[rt])) { + if (!UnwMemReadRegister(state, address, &state->regData[rt])) return UNWIND_DREAD_W_FAIL; - } } } /* @@ -459,31 +442,20 @@ UnwResult UnwStartThumb(UnwState * const state) { uint8_t rn = (instr & 0xF); uint8_t rt = (instr2 & 0xF000) >> 12; uint16_t imm8 = (instr2 & 0xFF); - bool P = (instr2 & 0x400) ? true : false; - bool U = (instr2 & 0x200) ? true : false; - bool W = (instr2 & 0x100) ? true : false; + bool P = !!(instr2 & 0x400); + bool U = !!(instr2 & 0x200); + bool W = !!(instr2 & 0x100); - if (!M_IsOriginValid(state->regData[rn].o)) { + if (!M_IsOriginValid(state->regData[rn].o)) state->regData[rt].o = state->regData[rn].o; - } else { - uint32_t offaddress = state->regData[rn].v + imm8; - if (U) offaddress += imm8; - else offaddress -= imm8; - - uint32_t address; - if (P) { - address = offaddress; - } else { - address = state->regData[rn].v; - } + else { + uint32_t offaddress = state->regData[rn].v + (U ? imm8 + imm8 : 0), + address = P ? offaddress : state->regData[rn].v; - if(!UnwMemReadRegister(state, address, &state->regData[rt])) { + if (!UnwMemReadRegister(state, address, &state->regData[rt])) return UNWIND_DREAD_W_FAIL; - } - if (W) { - state->regData[rn].v = offaddress; - } + if (W) state->regData[rn].v = offaddress; } } /* @@ -493,30 +465,28 @@ UnwResult UnwStartThumb(UnwState * const state) { * Where Rt is PC, Rn value is known, Rm is not known or unknown */ else if ((instr & 0xFFF0) == 0xF850 && (instr2 & 0x0FC0) == 0x0000) { - uint8_t rn = (instr & 0xF); - uint8_t rt = (instr2 & 0xF000) >> 12; - uint8_t rm = (instr2 & 0xF); - uint8_t imm2 = (instr2 & 0x30) >> 4; + const uint8_t rn = (instr & 0xF), + rt = (instr2 & 0xF000) >> 12, + rm = (instr2 & 0xF), + imm2 = (instr2 & 0x30) >> 4; - if (!M_IsOriginValid(state->regData[rn].o) || - !M_IsOriginValid(state->regData[rm].o)) { + if (!M_IsOriginValid(state->regData[rn].o) || !M_IsOriginValid(state->regData[rm].o)) { /* If Rt is PC, and Rn is known, then do an exception and assume Rm equals 0 => This takes the first case in a switch() */ if (rt == 15 && M_IsOriginValid(state->regData[rn].o)) { uint32_t address = state->regData[rn].v; - if(!UnwMemReadRegister(state, address, &state->regData[rt])) { + if (!UnwMemReadRegister(state, address, &state->regData[rt])) return UNWIND_DREAD_W_FAIL; - } - } else { - /* Propagate unknown value */ - state->regData[rt].o = state->regData[rn].o; } - } else { + else /* Propagate unknown value */ + state->regData[rt].o = state->regData[rn].o; + + } + else { uint32_t address = state->regData[rn].v + (state->regData[rm].v << imm2); - if(!UnwMemReadRegister(state, address, &state->regData[rt])) { + if (!UnwMemReadRegister(state, address, &state->regData[rt])) return UNWIND_DREAD_W_FAIL; - } } } else { @@ -533,14 +503,14 @@ UnwResult UnwStartThumb(UnwState * const state) { * LSR Rd, Rs, #Offset5 * ASR Rd, Rs, #Offset5 */ - else if((instr & 0xE000) == 0x0000 && (instr & 0x1800) != 0x1800) { + else if ((instr & 0xE000) == 0x0000 && (instr & 0x1800) != 0x1800) { bool signExtend; - uint8_t op = (instr & 0x1800) >> 11; - uint8_t offset5 = (instr & 0x07C0) >> 6; - uint8_t rs = (instr & 0x0038) >> 3; - uint8_t rd = (instr & 0x0007); + const uint8_t op = (instr & 0x1800) >> 11, + offset5 = (instr & 0x07C0) >> 6, + rs = (instr & 0x0038) >> 3, + rd = (instr & 0x0007); - switch(op) { + switch (op) { case 0: /* LSL */ UnwPrintd6("LSL r%d, r%d, #%d\t; r%d %s", rd, rs, offset5, rs, M_Origin2Str(state->regData[rs].o)); state->regData[rd].v = state->regData[rs].v << offset5; @@ -558,11 +528,9 @@ UnwResult UnwStartThumb(UnwState * const state) { case 2: /* ASR */ UnwPrintd6("ASL r%d, r%d, #%d\t; r%d %s", rd, rs, offset5, rs, M_Origin2Str(state->regData[rs].o)); - signExtend = (state->regData[rs].v & 0x8000) ? true : false; + signExtend = !!(state->regData[rs].v & 0x8000); state->regData[rd].v = state->regData[rs].v >> offset5; - if(signExtend) { - state->regData[rd].v |= 0xFFFFFFFF << (32 - offset5); - } + if (signExtend) state->regData[rd].v |= 0xFFFFFFFF << (32 - offset5); state->regData[rd].o = state->regData[rs].o; state->regData[rd].o |= REG_VAL_ARITHMETIC; break; @@ -574,9 +542,9 @@ UnwResult UnwStartThumb(UnwState * const state) { * SUB Rd, Rs, Rn * SUB Rd, Rs, #Offset3 */ - else if((instr & 0xF800) == 0x1800) { - bool I = (instr & 0x0400) ? true : false; - bool op = (instr & 0x0200) ? true : false; + else if ((instr & 0xF800) == 0x1800) { + bool I = !!(instr & 0x0400); + bool op = !!(instr & 0x0200); uint8_t rn = (instr & 0x01C0) >> 6; uint8_t rs = (instr & 0x0038) >> 3; uint8_t rd = (instr & 0x0007); @@ -584,36 +552,24 @@ UnwResult UnwStartThumb(UnwState * const state) { /* Print decoding */ UnwPrintd6("%s r%d, r%d, %c%d\t;",op ? "SUB" : "ADD",rd, rs,I ? '#' : 'r',rn); UnwPrintd5("r%d %s, r%d %s",rd, M_Origin2Str(state->regData[rd].o),rs, M_Origin2Str(state->regData[rs].o)); - if(!I) { + if (!I) { UnwPrintd3(", r%d %s", rn, M_Origin2Str(state->regData[rn].o)); /* Perform calculation */ - if(op) { - state->regData[rd].v = state->regData[rs].v - state->regData[rn].v; - } - else { - state->regData[rd].v = state->regData[rs].v + state->regData[rn].v; - } + state->regData[rd].v = state->regData[rs].v + (op ? -state->regData[rn].v : state->regData[rn].v); /* Propagate the origin */ - if(M_IsOriginValid(state->regData[rs].o) && - M_IsOriginValid(state->regData[rn].o)) { + if (M_IsOriginValid(state->regData[rs].o) && M_IsOriginValid(state->regData[rn].o)) { state->regData[rd].o = state->regData[rs].o; state->regData[rd].o |= REG_VAL_ARITHMETIC; } - else { + else state->regData[rd].o = REG_VAL_INVALID; - } } else { /* Perform calculation */ - if(op) { - state->regData[rd].v = state->regData[rs].v - rn; - } - else { - state->regData[rd].v = state->regData[rs].v + rn; - } + state->regData[rd].v = state->regData[rs].v + (op ? -rn : rn); /* Propagate the origin */ state->regData[rd].o = state->regData[rs].o; @@ -626,13 +582,13 @@ UnwResult UnwStartThumb(UnwState * const state) { * ADD Rd, #Offset8 * SUB Rd, #Offset8 */ - else if((instr & 0xE000) == 0x2000) { + else if ((instr & 0xE000) == 0x2000) { uint8_t op = (instr & 0x1800) >> 11; uint8_t rd = (instr & 0x0700) >> 8; uint8_t offset8 = (instr & 0x00FF); - switch(op) { + switch (op) { case 0: /* MOV */ UnwPrintd3("MOV r%d, #0x%x", rd, offset8); state->regData[rd].v = offset8; @@ -675,7 +631,7 @@ UnwResult UnwStartThumb(UnwState * const state) { * BIC Rd, Rs * MVN Rd, Rs */ - else if((instr & 0xFC00) == 0x4000) { + else if ((instr & 0xFC00) == 0x4000) { uint8_t op = (instr & 0x03C0) >> 6; uint8_t rs = (instr & 0x0038) >> 3; uint8_t rd = (instr & 0x0007); @@ -688,7 +644,7 @@ UnwResult UnwStartThumb(UnwState * const state) { "ORR", "MUL", "BIC", "MVN" }; #endif /* Print the mnemonic and registers */ - switch(op) { + switch (op) { case 0: /* AND */ case 1: /* EOR */ case 2: /* LSL */ @@ -720,7 +676,7 @@ UnwResult UnwStartThumb(UnwState * const state) { } /* Perform operation */ - switch(op) { + switch (op) { case 0: /* AND */ state->regData[rd].v &= state->regData[rs].v; break; @@ -738,7 +694,7 @@ UnwResult UnwStartThumb(UnwState * const state) { break; case 4: /* ASR */ - if(state->regData[rd].v & 0x80000000) { + if (state->regData[rd].v & 0x80000000) { state->regData[rd].v >>= state->regData[rs].v; state->regData[rd].v |= 0xFFFFFFFF << (32 - state->regData[rs].v); } @@ -782,7 +738,7 @@ UnwResult UnwStartThumb(UnwState * const state) { } /* Propagate data origins */ - switch(op) { + switch (op) { case 0: /* AND */ case 1: /* EOR */ case 2: /* LSL */ @@ -792,13 +748,12 @@ UnwResult UnwStartThumb(UnwState * const state) { case 12: /* ORR */ case 13: /* MUL */ case 14: /* BIC */ - if(M_IsOriginValid(state->regData[rd].o) && M_IsOriginValid(state->regData[rs].o)) { + if (M_IsOriginValid(state->regData[rd].o) && M_IsOriginValid(state->regData[rs].o)) { state->regData[rd].o = state->regData[rs].o; state->regData[rd].o |= REG_VAL_ARITHMETIC; } - else { + else state->regData[rd].o = REG_VAL_INVALID; - } break; case 5: /* ADC */ @@ -825,7 +780,7 @@ UnwResult UnwStartThumb(UnwState * const state) { * CMP Hd, Rs * MOV Hd, Hs */ - else if((instr & 0xFC00) == 0x4400) { + else if ((instr & 0xFC00) == 0x4400) { uint8_t op = (instr & 0x0300) >> 8; bool h1 = (instr & 0x0080) ? true: false; bool h2 = (instr & 0x0040) ? true: false; @@ -833,12 +788,10 @@ UnwResult UnwStartThumb(UnwState * const state) { uint8_t rhd = (instr & 0x0007); /* Adjust the register numbers */ - if(h2) - rhs += 8; - if(h1) - rhd += 8; + if (h2) rhs += 8; + if (h1) rhd += 8; - switch(op) { + switch (op) { case 0: /* ADD */ UnwPrintd5("ADD r%d, r%d\t; r%d %s", rhd, rhs, rhs, M_Origin2Str(state->regData[rhs].o)); state->regData[rhd].v += state->regData[rhs].v; @@ -861,28 +814,25 @@ UnwResult UnwStartThumb(UnwState * const state) { UnwPrintd4("BX r%d\t; r%d %s\n", rhs, rhs, M_Origin2Str(state->regData[rhs].o)); /* Only follow BX if the data was from the stack or BX LR */ - if(rhs == 14 || state->regData[rhs].o == REG_VAL_FROM_STACK) { + if (rhs == 14 || state->regData[rhs].o == REG_VAL_FROM_STACK) { UnwPrintd2(" Return PC=0x%x\n", state->regData[rhs].v & (~0x1)); /* Report the return address, including mode bit */ - if(!UnwReportRetAddr(state, state->regData[rhs].v)) { + if (!UnwReportRetAddr(state, state->regData[rhs].v)) return UNWIND_TRUNCATED; - } /* Update the PC */ state->regData[15].v = state->regData[rhs].v; /* Determine the new mode */ - if(state->regData[rhs].v & 0x1) { + if (state->regData[rhs].v & 0x1) { /* Branching to THUMB */ /* Account for the auto-increment which isn't needed */ state->regData[15].v -= 2; } - else { - /* Branch to ARM */ + else /* Branch to ARM */ return UnwStartArm(state); - } } else { UnwPrintd4("\nError: BX to invalid register: r%d = 0x%x (%s)\n", rhs, state->regData[rhs].o, M_Origin2Str(state->regData[rhs].o)); @@ -893,7 +843,7 @@ UnwResult UnwStartThumb(UnwState * const state) { /* Format 9: PC-relative load * LDR Rd,[PC, #imm] */ - else if((instr & 0xF800) == 0x4800) { + else if ((instr & 0xF800) == 0x4800) { uint8_t rd = (instr & 0x0700) >> 8; uint8_t word8 = (instr & 0x00FF); uint32_t address; @@ -903,19 +853,18 @@ UnwResult UnwStartThumb(UnwState * const state) { UnwPrintd3("LDR r%d, 0x%08x", rd, address); - if(!UnwMemReadRegister(state, address, &state->regData[rd])) { + if (!UnwMemReadRegister(state, address, &state->regData[rd])) return UNWIND_DREAD_W_FAIL; - } } /* Format 13: add offset to Stack Pointer * ADD sp,#+imm * ADD sp,#-imm */ - else if((instr & 0xFF00) == 0xB000) { + else if ((instr & 0xFF00) == 0xB000) { uint8_t value = (instr & 0x7F) * 4; /* Check the negative bit */ - if((instr & 0x80) != 0) { + if ((instr & 0x80) != 0) { UnwPrintd2("SUB sp,#0x%x", value); state->regData[13].v -= value; } @@ -930,29 +879,27 @@ UnwResult UnwStartThumb(UnwState * const state) { * POP {Rlist} * POP {Rlist, PC} */ - else if((instr & 0xF600) == 0xB400) { - bool L = (instr & 0x0800) ? true : false; - bool R = (instr & 0x0100) ? true : false; + else if ((instr & 0xF600) == 0xB400) { + bool L = !!(instr & 0x0800); + bool R = !!(instr & 0x0100); uint8_t rList = (instr & 0x00FF); - if(L) { + if (L) { uint8_t r; /* Load from memory: POP */ UnwPrintd2("POP {Rlist%s}\n", R ? ", PC" : ""); - for(r = 0; r < 8; r++) { - if(rList & (0x1 << r)) { + for (r = 0; r < 8; r++) { + if (rList & (0x1 << r)) { /* Read the word */ - if(!UnwMemReadRegister(state, state->regData[13].v, &state->regData[r])) { + if (!UnwMemReadRegister(state, state->regData[13].v, &state->regData[r])) return UNWIND_DREAD_W_FAIL; - } /* Alter the origin to be from the stack if it was valid */ - if(M_IsOriginValid(state->regData[r].o)) { + if (M_IsOriginValid(state->regData[r].o)) state->regData[r].o = REG_VAL_FROM_STACK; - } state->regData[13].v += 4; @@ -961,14 +908,13 @@ UnwResult UnwStartThumb(UnwState * const state) { } /* Check if the PC is to be popped */ - if(R) { + if (R) { /* Get the return address */ - if(!UnwMemReadRegister(state, state->regData[13].v, &state->regData[15])) { + if (!UnwMemReadRegister(state, state->regData[13].v, &state->regData[15])) return UNWIND_DREAD_W_FAIL; - } /* Alter the origin to be from the stack if it was valid */ - if(!M_IsOriginValid(state->regData[15].o)) { + if (!M_IsOriginValid(state->regData[15].o)) { /* Return address is not valid */ UnwPrintd1("PC popped with invalid address\n"); return UNWIND_FAILURE; @@ -978,7 +924,7 @@ UnwResult UnwStartThumb(UnwState * const state) { * the caller was from Thumb. This would allow return * by BX for interworking APCS. */ - if((state->regData[15].v & 0x1) == 0) { + if ((state->regData[15].v & 0x1) == 0) { UnwPrintd2("Warning: Return address not to Thumb: 0x%08x\n", state->regData[15].v); /* Pop into the PC will not switch mode */ @@ -986,9 +932,8 @@ UnwResult UnwStartThumb(UnwState * const state) { } /* Store the return address */ - if(!UnwReportRetAddr(state, state->regData[15].v)) { + if (!UnwReportRetAddr(state, state->regData[15].v)) return UNWIND_TRUNCATED; - } /* Now have the return address */ UnwPrintd2(" Return PC=%x\n", state->regData[15].v); @@ -1008,26 +953,24 @@ UnwResult UnwStartThumb(UnwState * const state) { UnwPrintd2("PUSH {Rlist%s}", R ? ", LR" : ""); /* Check if the LR is to be pushed */ - if(R) { + if (R) { UnwPrintd3("\n lr = 0x%08x\t; %s", state->regData[14].v, M_Origin2Str(state->regData[14].o)); state->regData[13].v -= 4; /* Write the register value to memory */ - if(!UnwMemWriteRegister(state, state->regData[13].v, &state->regData[14])) { + if (!UnwMemWriteRegister(state, state->regData[13].v, &state->regData[14])) return UNWIND_DWRITE_W_FAIL; - } } - for(r = 7; r >= 0; r--) { - if(rList & (0x1 << r)) { + for (r = 7; r >= 0; r--) { + if (rList & (0x1 << r)) { UnwPrintd4("\n r%d = 0x%08x\t; %s", r, state->regData[r].v, M_Origin2Str(state->regData[r].o)); state->regData[13].v -= 4; - if(!UnwMemWriteRegister(state, state->regData[13].v, &state->regData[r])) { + if (!UnwMemWriteRegister(state, state->regData[13].v, &state->regData[r])) return UNWIND_DWRITE_W_FAIL; - } } } } @@ -1037,7 +980,7 @@ UnwResult UnwStartThumb(UnwState * const state) { * Conditional branches * Bcond */ - else if((instr & 0xF000) == 0xD000) { + else if ((instr & 0xF000) == 0xD000) { int32_t branchValue = (instr & 0xFF); if (branchValue & 0x80) branchValue |= 0xFFFFFF00; @@ -1066,7 +1009,7 @@ UnwResult UnwStartThumb(UnwState * const state) { /* Format 18: unconditional branch * B label */ - else if((instr & 0xF800) == 0xE000) { + else if ((instr & 0xF800) == 0xE000) { uint32_t v; int32_t branchValue = signExtend11(instr & 0x07FF); @@ -1106,8 +1049,7 @@ UnwResult UnwStartThumb(UnwState * const state) { UnwPrintd1("\n"); /* Should never hit the reset vector */ - if(state->regData[15].v == 0) - return UNWIND_RESET; + if (state->regData[15].v == 0) return UNWIND_RESET; /* Check next address */ state->regData[15].v += 2; @@ -1115,11 +1057,9 @@ UnwResult UnwStartThumb(UnwState * const state) { /* Garbage collect the memory hash (used only for the stack) */ UnwMemHashGC(state); - t--; - if(t == 0) - return UNWIND_EXHAUSTED; + if (--t == 0) return UNWIND_EXHAUSTED; - } while(!found); + } while (!found); return UNWIND_SUCCESS; } diff --git a/Marlin/src/HAL/shared/backtrace/unwarmmem.cpp b/Marlin/src/HAL/shared/backtrace/unwarmmem.cpp index b83684171..cf9ac414c 100644 --- a/Marlin/src/HAL/shared/backtrace/unwarmmem.cpp +++ b/Marlin/src/HAL/shared/backtrace/unwarmmem.cpp @@ -19,7 +19,7 @@ #include "unwarmmem.h" #include "unwarm.h" -#define M_IsIdxUsed(a, v) (((a)[v >> 3] & (1 << (v & 0x7))) ? true : false) +#define M_IsIdxUsed(a, v) !!((a)[v >> 3] & (1 << (v & 0x7))) #define M_SetIdxUsed(a, v) ((a)[v >> 3] |= (1 << (v & 0x7))) #define M_ClrIdxUsed(a, v) ((a)[v >> 3] &= ~(1 << (v & 0x7))) @@ -34,11 +34,9 @@ static int16_t memHashIndex(MemData * const memData, const uint32_t addr) { do { /* Check if the element is occupied */ - if(M_IsIdxUsed(memData->used, s)) { + if (M_IsIdxUsed(memData->used, s)) { /* Check if it is occupied with the sought data */ - if(memData->a[s] == addr) { - return s; - } + if (memData->a[s] == addr) return s; } else { /* Item is free, this is where the item should be stored */ @@ -47,10 +45,8 @@ static int16_t memHashIndex(MemData * const memData, const uint32_t addr) { /* Search the next entry */ s++; - if(s > MEM_HASH_SIZE) { - s = 0; - } - } while(s != v); + if (s > MEM_HASH_SIZE) s = 0; + } while (s != v); /* Search failed, hash is full and the address not stored */ return -1; @@ -58,9 +54,9 @@ static int16_t memHashIndex(MemData * const memData, const uint32_t addr) { bool UnwMemHashRead(MemData * const memData, uint32_t addr,uint32_t * const data, bool * const tracked) { - int16_t i = memHashIndex(memData, addr); + const int16_t i = memHashIndex(memData, addr); - if(i >= 0 && M_IsIdxUsed(memData->used, i) && memData->a[i] == addr) { + if (i >= 0 && M_IsIdxUsed(memData->used, i) && memData->a[i] == addr) { *data = memData->v[i]; *tracked = M_IsIdxUsed(memData->tracked, i); return true; @@ -72,44 +68,36 @@ bool UnwMemHashRead(MemData * const memData, uint32_t addr,uint32_t * const data } bool UnwMemHashWrite(MemData * const memData, uint32_t addr, uint32_t val, bool valValid) { + const int16_t i = memHashIndex(memData, addr); + if (i < 0) return false; /* Hash full */ - int16_t i = memHashIndex(memData, addr); + /* Store the item */ + memData->a[i] = addr; + M_SetIdxUsed(memData->used, i); - if(i < 0){ - /* Hash full */ - return false; + if (valValid) { + memData->v[i] = val; + M_SetIdxUsed(memData->tracked, i); } else { - /* Store the item */ - memData->a[i] = addr; - M_SetIdxUsed(memData->used, i); - - if(valValid) - { - memData->v[i] = val; - M_SetIdxUsed(memData->tracked, i); - } - else { - #ifdef UNW_DEBUG - memData->v[i] = 0xDEADBEEF; - #endif - M_ClrIdxUsed(memData->tracked, i); - } - - return true; + #ifdef UNW_DEBUG + memData->v[i] = 0xDEADBEEF; + #endif + M_ClrIdxUsed(memData->tracked, i); } + + return true; } void UnwMemHashGC(UnwState * const state) { const uint32_t minValidAddr = state->regData[13].v; MemData * const memData = &state->memData; - uint16_t t; + uint16_t t; - for(t = 0; t < MEM_HASH_SIZE; t++) { - if(M_IsIdxUsed(memData->used, t) && (memData->a[t] < minValidAddr)) { + for (t = 0; t < MEM_HASH_SIZE; t++) { + if (M_IsIdxUsed(memData->used, t) && (memData->a[t] < minValidAddr)) { UnwPrintd3("MemHashGC: Free elem %d, addr 0x%08x\n", t, memData->a[t]); - M_ClrIdxUsed(memData->used, t); } } diff --git a/Marlin/src/HAL/shared/backtrace/unwinder.cpp b/Marlin/src/HAL/shared/backtrace/unwinder.cpp index 7c5af02cd..bde589943 100644 --- a/Marlin/src/HAL/shared/backtrace/unwinder.cpp +++ b/Marlin/src/HAL/shared/backtrace/unwinder.cpp @@ -33,13 +33,11 @@ static int HasUnwindTableInfo(void) { } UnwResult UnwindStart(UnwindFrame* frame, const UnwindCallbacks *cb, void *data) { - if (HasUnwindTableInfo()) { - /* We have unwind information tables */ return UnwindByTableStart(frame, cb, data); - - } else { + } + else { /* We don't have unwind information tables */ UnwState state; @@ -48,12 +46,7 @@ UnwResult UnwindStart(UnwindFrame* frame, const UnwindCallbacks *cb, void *data) UnwInitState(&state, cb, data, frame->pc, frame->sp); /* Check the Thumb bit */ - if(frame->pc & 0x1) { - return UnwStartThumb(&state); - } - else { - return UnwStartArm(&state); - } + return (frame->pc & 0x1) ? UnwStartThumb(&state) : UnwStartArm(&state); } } #endif diff --git a/Marlin/src/feature/emergency_parser.h b/Marlin/src/feature/emergency_parser.h index 5494ffda0..4506313cc 100644 --- a/Marlin/src/feature/emergency_parser.h +++ b/Marlin/src/feature/emergency_parser.h @@ -143,7 +143,7 @@ public: break; case EP_M876: - switch(c) { + switch (c) { case ' ': break; case 'S': state = EP_M876S; break; default: state = EP_IGNORE; break; diff --git a/Marlin/src/feature/prusa_MMU2/mmu2.cpp b/Marlin/src/feature/prusa_MMU2/mmu2.cpp index d6c4c2338..92179774d 100644 --- a/Marlin/src/feature/prusa_MMU2/mmu2.cpp +++ b/Marlin/src/feature/prusa_MMU2/mmu2.cpp @@ -557,7 +557,7 @@ void MMU2::toolChange(const char* special) { set_runout_valid(false); KEEPALIVE_STATE(IN_HANDLER); - switch(*special) { + switch (*special) { case '?': { uint8_t index = mmu2_chooseFilament(); while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100); diff --git a/Marlin/src/gcode/calibrate/G425.cpp b/Marlin/src/gcode/calibrate/G425.cpp index 8541df8b0..844623580 100644 --- a/Marlin/src/gcode/calibrate/G425.cpp +++ b/Marlin/src/gcode/calibrate/G425.cpp @@ -248,7 +248,7 @@ inline void probe_side(measurements_t &m, const float uncertainty, const side_t park_above_object(m, uncertainty); - switch(side) { + switch (side) { case TOP: { const float measurement = measure(Z_AXIS, -1, true, &m.backlash[TOP], uncertainty); m.obj_center[Z_AXIS] = measurement - dimensions[Z_AXIS] / 2; diff --git a/Marlin/src/lcd/dogm/u8g_dev_ssd1306_sh1106_128x64_I2C.cpp b/Marlin/src/lcd/dogm/u8g_dev_ssd1306_sh1106_128x64_I2C.cpp index be984334e..59ec0f2b2 100644 --- a/Marlin/src/lcd/dogm/u8g_dev_ssd1306_sh1106_128x64_I2C.cpp +++ b/Marlin/src/lcd/dogm/u8g_dev_ssd1306_sh1106_128x64_I2C.cpp @@ -112,7 +112,7 @@ static const uint8_t u8g_dev_sh1106_128x64_init_seq_2_wire[] PROGMEM = { }; uint8_t u8g_dev_sh1106_128x64_2x_2_wire_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) { - switch(msg) { + switch (msg) { case U8G_DEV_MSG_INIT: u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_sh1106_128x64_init_seq_2_wire); @@ -180,7 +180,7 @@ static const uint8_t u8g_dev_ssd1306_128x64_init_seq_2_wire[] PROGMEM = { }; uint8_t u8g_dev_ssd1306_128x64_2x_2_wire_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) { - switch(msg) { + switch (msg) { case U8G_DEV_MSG_INIT: u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_ssd1306_128x64_init_seq_2_wire); @@ -227,7 +227,7 @@ u8g_dev_t u8g_dev_ssd1306_128x64_2x_i2c_2_wire = { u8g_dev_ssd1306_128x64_2x_2_w uint8_t u8g_WriteEscSeqP_2_wire(u8g_t *u8g, u8g_dev_t *dev, const uint8_t *esc_seq) { uint8_t is_escape = 0; uint8_t value; - for(;;) { + for (;;) { value = u8g_pgm_read(esc_seq); if (is_escape == 0) { if (value != 255) { diff --git a/Marlin/src/lcd/dogm/u8g_dev_st7565_64128n_HAL.cpp b/Marlin/src/lcd/dogm/u8g_dev_st7565_64128n_HAL.cpp index aac80fda3..17d93e9a2 100644 --- a/Marlin/src/lcd/dogm/u8g_dev_st7565_64128n_HAL.cpp +++ b/Marlin/src/lcd/dogm/u8g_dev_st7565_64128n_HAL.cpp @@ -149,7 +149,7 @@ static const uint8_t u8g_dev_st7565_64128n_HAL_sleep_off[] PROGMEM = { }; uint8_t u8g_dev_st7565_64128n_HAL_fn(u8g_t *u8g, u8g_dev_t *dev, const uint8_t msg, void *arg) { - switch(msg) { + switch (msg) { case U8G_DEV_MSG_INIT: u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_400NS); u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7565_64128n_HAL_init_seq); @@ -183,7 +183,7 @@ uint8_t u8g_dev_st7565_64128n_HAL_fn(u8g_t *u8g, u8g_dev_t *dev, const uint8_t m } uint8_t u8g_dev_st7565_64128n_HAL_2x_fn(u8g_t *u8g, u8g_dev_t *dev, const uint8_t msg, void *arg) { - switch(msg) { + switch (msg) { case U8G_DEV_MSG_INIT: u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_400NS); u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7565_64128n_HAL_init_seq); diff --git a/Marlin/src/lcd/dogm/u8g_dev_st7920_128x64_HAL.cpp b/Marlin/src/lcd/dogm/u8g_dev_st7920_128x64_HAL.cpp index 5d99e4240..ed5036f30 100644 --- a/Marlin/src/lcd/dogm/u8g_dev_st7920_128x64_HAL.cpp +++ b/Marlin/src/lcd/dogm/u8g_dev_st7920_128x64_HAL.cpp @@ -106,7 +106,7 @@ void clear_graphics_DRAM(u8g_t *u8g, u8g_dev_t *dev) { } uint8_t u8g_dev_st7920_128x64_HAL_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) { - switch(msg) { + switch (msg) { case U8G_DEV_MSG_INIT: u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_400NS); u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7920_128x64_HAL_init_seq); @@ -149,7 +149,7 @@ uint8_t u8g_dev_st7920_128x64_HAL_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, vo } uint8_t u8g_dev_st7920_128x64_HAL_4x_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) { - switch(msg) { + switch (msg) { case U8G_DEV_MSG_INIT: u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_400NS); u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7920_128x64_HAL_init_seq); diff --git a/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp b/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp index e142953e5..8f295ab0f 100644 --- a/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp +++ b/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp @@ -125,7 +125,7 @@ uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, u uint16_t buffer[256]; uint32_t i, j, k; - switch(msg) { + switch (msg) { case U8G_DEV_MSG_INIT: dev->com_fn(u8g, U8G_COM_MSG_INIT, U8G_SPI_CLK_CYCLE_NONE, &lcd_id); if (lcd_id == 0x040404) return 0; // No connected display on FSMC diff --git a/Marlin/src/lcd/dogm/u8g_dev_uc1701_mini12864_HAL.cpp b/Marlin/src/lcd/dogm/u8g_dev_uc1701_mini12864_HAL.cpp index 9e4489e3f..84adc25b4 100644 --- a/Marlin/src/lcd/dogm/u8g_dev_uc1701_mini12864_HAL.cpp +++ b/Marlin/src/lcd/dogm/u8g_dev_uc1701_mini12864_HAL.cpp @@ -109,7 +109,7 @@ static const uint8_t u8g_dev_uc1701_mini12864_HAL_data_start[] PROGMEM = { }; uint8_t u8g_dev_uc1701_mini12864_HAL_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) { - switch(msg) { + switch (msg) { case U8G_DEV_MSG_INIT: u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); u8g_WriteEscSeqP(u8g, dev, u8g_dev_uc1701_mini12864_HAL_init_seq); @@ -138,7 +138,7 @@ uint8_t u8g_dev_uc1701_mini12864_HAL_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, } uint8_t u8g_dev_uc1701_mini12864_HAL_2x_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) { - switch(msg) { + switch (msg) { case U8G_DEV_MSG_INIT: u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); u8g_WriteEscSeqP(u8g, dev, u8g_dev_uc1701_mini12864_HAL_init_seq); diff --git a/Marlin/src/sd/Sd2Card.cpp b/Marlin/src/sd/Sd2Card.cpp index b734d1744..ab221e497 100644 --- a/Marlin/src/sd/Sd2Card.cpp +++ b/Marlin/src/sd/Sd2Card.cpp @@ -339,7 +339,7 @@ bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) { #if ENABLED(SD_CHECK_AND_RETRY) uint8_t retryCnt = 3; - for(;;) { + for (;;) { if (cardCommand(CMD17, blockNumber)) error(SD_CARD_ERROR_CMD17); else if (readData(dst, 512)) diff --git a/Marlin/src/sd/usb_flashdrive/lib/Usb.cpp b/Marlin/src/sd/usb_flashdrive/lib/Usb.cpp index 3158f776a..6d0f92069 100644 --- a/Marlin/src/sd/usb_flashdrive/lib/Usb.cpp +++ b/Marlin/src/sd/usb_flashdrive/lib/Usb.cpp @@ -35,98 +35,98 @@ static uint8_t usb_task_state; /* constructor */ USB::USB() : bmHubPre(0) { - usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE; //set up state machine - init(); + usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE; //set up state machine + init(); } /* Initialize data structures */ void USB::init() { - //devConfigIndex = 0; - bmHubPre = 0; + //devConfigIndex = 0; + bmHubPre = 0; } uint8_t USB::getUsbTaskState(void) { - return ( usb_task_state); + return ( usb_task_state); } void USB::setUsbTaskState(uint8_t state) { - usb_task_state = state; + usb_task_state = state; } EpInfo* USB::getEpInfoEntry(uint8_t addr, uint8_t ep) { - UsbDevice *p = addrPool.GetUsbDevicePtr(addr); + UsbDevice *p = addrPool.GetUsbDevicePtr(addr); - if(!p || !p->epinfo) - return NULL; + if (!p || !p->epinfo) + return NULL; - EpInfo *pep = p->epinfo; + EpInfo *pep = p->epinfo; - for(uint8_t i = 0; i < p->epcount; i++) { - if((pep)->epAddr == ep) - return pep; + for (uint8_t i = 0; i < p->epcount; i++) { + if ((pep)->epAddr == ep) + return pep; - pep++; - } - return NULL; + pep++; + } + return NULL; } /* set device table entry */ /* each device is different and has different number of endpoints. This function plugs endpoint record structure, defined in application, to devtable */ uint8_t USB::setEpInfoEntry(uint8_t addr, uint8_t epcount, EpInfo* eprecord_ptr) { - if(!eprecord_ptr) - return USB_ERROR_INVALID_ARGUMENT; + if (!eprecord_ptr) + return USB_ERROR_INVALID_ARGUMENT; - UsbDevice *p = addrPool.GetUsbDevicePtr(addr); + UsbDevice *p = addrPool.GetUsbDevicePtr(addr); - if(!p) - return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; + if (!p) + return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; - p->address.devAddress = addr; - p->epinfo = eprecord_ptr; - p->epcount = epcount; + p->address.devAddress = addr; + p->epinfo = eprecord_ptr; + p->epcount = epcount; - return 0; + return 0; } uint8_t USB::SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t *nak_limit) { - UsbDevice *p = addrPool.GetUsbDevicePtr(addr); + UsbDevice *p = addrPool.GetUsbDevicePtr(addr); - if(!p) - return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; + if (!p) + return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; - if(!p->epinfo) - return USB_ERROR_EPINFO_IS_NULL; + if (!p->epinfo) + return USB_ERROR_EPINFO_IS_NULL; - *ppep = getEpInfoEntry(addr, ep); + *ppep = getEpInfoEntry(addr, ep); - if(!*ppep) - return USB_ERROR_EP_NOT_FOUND_IN_TBL; + if (!*ppep) + return USB_ERROR_EP_NOT_FOUND_IN_TBL; - *nak_limit = (0x0001UL << (((*ppep)->bmNakPower > USB_NAK_MAX_POWER) ? USB_NAK_MAX_POWER : (*ppep)->bmNakPower)); - (*nak_limit)--; - /* - USBTRACE2("\r\nAddress: ", addr); - USBTRACE2(" EP: ", ep); - USBTRACE2(" NAK Power: ",(*ppep)->bmNakPower); - USBTRACE2(" NAK Limit: ", nak_limit); - USBTRACE("\r\n"); - */ - regWr(rPERADDR, addr); //set peripheral address + *nak_limit = (0x0001UL << (((*ppep)->bmNakPower > USB_NAK_MAX_POWER) ? USB_NAK_MAX_POWER : (*ppep)->bmNakPower)); + (*nak_limit)--; + /* + USBTRACE2("\r\nAddress: ", addr); + USBTRACE2(" EP: ", ep); + USBTRACE2(" NAK Power: ",(*ppep)->bmNakPower); + USBTRACE2(" NAK Limit: ", nak_limit); + USBTRACE("\r\n"); + */ + regWr(rPERADDR, addr); //set peripheral address - uint8_t mode = regRd(rMODE); + uint8_t mode = regRd(rMODE); - //Serial.print("\r\nMode: "); - //Serial.println( mode, HEX); - //Serial.print("\r\nLS: "); - //Serial.println(p->lowspeed, HEX); + //Serial.print("\r\nMode: "); + //Serial.println( mode, HEX); + //Serial.print("\r\nLS: "); + //Serial.println(p->lowspeed, HEX); - // Set bmLOWSPEED and bmHUBPRE in case of low-speed device, reset them otherwise - regWr(rMODE, (p->lowspeed) ? mode | bmLOWSPEED | bmHubPre : mode & ~(bmHUBPRE | bmLOWSPEED)); + // Set bmLOWSPEED and bmHUBPRE in case of low-speed device, reset them otherwise + regWr(rMODE, (p->lowspeed) ? mode | bmLOWSPEED | bmHubPre : mode & ~(bmHUBPRE | bmLOWSPEED)); - return 0; + return 0; } /* Control transfer. Sets address, endpoint, fills control packet with necessary data, dispatches control packet, and initiates bulk IN transfer, */ @@ -136,166 +136,152 @@ uint8_t USB::SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t *nak_l /* 01-0f = non-zero HRSLT */ uint8_t USB::ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bRequest, uint8_t wValLo, uint8_t wValHi, - uint16_t wInd, uint16_t total, uint16_t nbytes, uint8_t* dataptr, USBReadParser *p) { - bool direction = false; //request direction, IN or OUT - uint8_t rcode; - SETUP_PKT setup_pkt; - - EpInfo *pep = NULL; - uint16_t nak_limit = 0; - - rcode = SetAddress(addr, ep, &pep, &nak_limit); - - if(rcode) - return rcode; - - direction = ((bmReqType & 0x80) > 0); - - /* fill in setup packet */ - setup_pkt.ReqType_u.bmRequestType = bmReqType; - setup_pkt.bRequest = bRequest; - setup_pkt.wVal_u.wValueLo = wValLo; - setup_pkt.wVal_u.wValueHi = wValHi; - setup_pkt.wIndex = wInd; - setup_pkt.wLength = total; - - bytesWr(rSUDFIFO, 8, (uint8_t*) & setup_pkt); //transfer to setup packet FIFO - - rcode = dispatchPkt(tokSETUP, ep, nak_limit); //dispatch packet - - if(rcode) //return HRSLT if not zero - return ( rcode); - - if(dataptr != NULL) //data stage, if present - { - if(direction) //IN transfer - { - uint16_t left = total; - - pep->bmRcvToggle = 1; //bmRCVTOG1; - - while(left) { - // Bytes read into buffer - uint16_t read = nbytes; - //uint16_t read = (leftbmRcvToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1; - continue; - } - - if(rcode) - return rcode; - - // Invoke callback function if inTransfer completed successfully and callback function pointer is specified - if(!rcode && p) - ((USBReadParser*)p)->Parse(read, dataptr, total - left); - - left -= read; - - if(read < nbytes) - break; - } - } else //OUT transfer - { - pep->bmSndToggle = 1; //bmSNDTOG1; - rcode = OutTransfer(pep, nak_limit, nbytes, dataptr); - } - if(rcode) //return error - return ( rcode); + uint16_t wInd, uint16_t total, uint16_t nbytes, uint8_t* dataptr, USBReadParser *p) { + bool direction = false; //request direction, IN or OUT + uint8_t rcode; + SETUP_PKT setup_pkt; + + EpInfo *pep = NULL; + uint16_t nak_limit = 0; + + rcode = SetAddress(addr, ep, &pep, &nak_limit); + if (rcode) return rcode; + + direction = ((bmReqType & 0x80) > 0); + + /* fill in setup packet */ + setup_pkt.ReqType_u.bmRequestType = bmReqType; + setup_pkt.bRequest = bRequest; + setup_pkt.wVal_u.wValueLo = wValLo; + setup_pkt.wVal_u.wValueHi = wValHi; + setup_pkt.wIndex = wInd; + setup_pkt.wLength = total; + + bytesWr(rSUDFIFO, 8, (uint8_t*) & setup_pkt); //transfer to setup packet FIFO + + rcode = dispatchPkt(tokSETUP, ep, nak_limit); //dispatch packet + if (rcode) return rcode; // Return HRSLT if not zero + + if (dataptr != NULL) { //data stage, if present + if (direction) { //IN transfer + uint16_t left = total; + pep->bmRcvToggle = 1; //bmRCVTOG1; + + while (left) { + // Bytes read into buffer + uint16_t read = nbytes; + //uint16_t read = (leftbmRcvToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1; + continue; } - // Status stage - return dispatchPkt((direction) ? tokOUTHS : tokINHS, ep, nak_limit); //GET if direction + + if (rcode) return rcode; + + // Invoke callback function if inTransfer completed successfully and callback function pointer is specified + if (!rcode && p) ((USBReadParser*)p)->Parse(read, dataptr, total - left); + + left -= read; + + if (read < nbytes) break; + } + } + else { //OUT transfer + pep->bmSndToggle = 1; //bmSNDTOG1; + rcode = OutTransfer(pep, nak_limit, nbytes, dataptr); + } + if (rcode) return rcode; // return error + } + // Status stage + return dispatchPkt((direction) ? tokOUTHS : tokINHS, ep, nak_limit); //GET if direction } /* IN transfer to arbitrary endpoint. Assumes PERADDR is set. Handles multiple packets if necessary. Transfers 'nbytes' bytes. */ /* Keep sending INs and writes data to memory area pointed by 'data' */ /* rcode 0 if no errors. rcode 01-0f is relayed from dispatchPkt(). Rcode f0 means RCVDAVIRQ error, - fe USB xfer timeout */ + fe USB xfer timeout */ uint8_t USB::inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t* data, uint8_t bInterval /*= 0*/) { - EpInfo *pep = NULL; - uint16_t nak_limit = 0; - - uint8_t rcode = SetAddress(addr, ep, &pep, &nak_limit); - - if(rcode) { - USBTRACE3("(USB::InTransfer) SetAddress Failed ", rcode, 0x81); - USBTRACE3("(USB::InTransfer) addr requested ", addr, 0x81); - USBTRACE3("(USB::InTransfer) ep requested ", ep, 0x81); - return rcode; - } - return InTransfer(pep, nak_limit, nbytesptr, data, bInterval); + EpInfo *pep = NULL; + uint16_t nak_limit = 0; + + uint8_t rcode = SetAddress(addr, ep, &pep, &nak_limit); + if (rcode) { + USBTRACE3("(USB::InTransfer) SetAddress Failed ", rcode, 0x81); + USBTRACE3("(USB::InTransfer) addr requested ", addr, 0x81); + USBTRACE3("(USB::InTransfer) ep requested ", ep, 0x81); + return rcode; + } + return InTransfer(pep, nak_limit, nbytesptr, data, bInterval); } uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, uint8_t* data, uint8_t bInterval /*= 0*/) { - uint8_t rcode = 0; - uint8_t pktsize; - - uint16_t nbytes = *nbytesptr; - //printf("Requesting %i bytes ", nbytes); - uint8_t maxpktsize = pep->maxPktSize; - - *nbytesptr = 0; - regWr(rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0); //set toggle value - - // use a 'break' to exit this loop - while(1) { - rcode = dispatchPkt(tokIN, pep->epAddr, nak_limit); //IN packet to EP-'endpoint'. Function takes care of NAKS. - if(rcode == hrTOGERR) { - // yes, we flip it wrong here so that next time it is actually correct! - pep->bmRcvToggle = (regRd(rHRSL) & bmRCVTOGRD) ? 0 : 1; - regWr(rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0); //set toggle value - continue; - } - if(rcode) { - //printf(">>>>>>>> Problem! dispatchPkt %2.2x\r\n", rcode); - break; //should be 0, indicating ACK. Else return error code. - } - /* check for RCVDAVIRQ and generate error if not present */ - /* the only case when absence of RCVDAVIRQ makes sense is when toggle error occurred. Need to add handling for that */ - if((regRd(rHIRQ) & bmRCVDAVIRQ) == 0) { - //printf(">>>>>>>> Problem! NO RCVDAVIRQ!\r\n"); - rcode = 0xf0; //receive error - break; - } - pktsize = regRd(rRCVBC); //number of received bytes - //printf("Got %i bytes \r\n", pktsize); - // This would be OK, but... - //assert(pktsize <= nbytes); - if(pktsize > nbytes) { - // This can happen. Use of assert on Arduino locks up the Arduino. - // So I will trim the value, and hope for the best. - //printf(">>>>>>>> Problem! Wanted %i bytes but got %i.\r\n", nbytes, pktsize); - pktsize = nbytes; - } - - int16_t mem_left = (int16_t)nbytes - *((int16_t*)nbytesptr); - - if(mem_left < 0) - mem_left = 0; - - data = bytesRd(rRCVFIFO, ((pktsize > mem_left) ? mem_left : pktsize), data); - - regWr(rHIRQ, bmRCVDAVIRQ); // Clear the IRQ & free the buffer - *nbytesptr += pktsize; // add this packet's byte count to total transfer length - - /* The transfer is complete under two conditions: */ - /* 1. The device sent a short packet (L.T. maxPacketSize) */ - /* 2. 'nbytes' have been transferred. */ - if((pktsize < maxpktsize) || (*nbytesptr >= nbytes)) // have we transferred 'nbytes' bytes? - { - // Save toggle value - pep->bmRcvToggle = ((regRd(rHRSL) & bmRCVTOGRD)) ? 1 : 0; - //printf("\r\n"); - rcode = 0; - break; - } else if(bInterval > 0) - delay(bInterval); // Delay according to polling interval - } //while( 1 ) - return ( rcode); + uint8_t rcode = 0; + uint8_t pktsize; + + uint16_t nbytes = *nbytesptr; + //printf("Requesting %i bytes ", nbytes); + uint8_t maxpktsize = pep->maxPktSize; + + *nbytesptr = 0; + regWr(rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0); //set toggle value + + // use a 'break' to exit this loop + for (;;) { + rcode = dispatchPkt(tokIN, pep->epAddr, nak_limit); //IN packet to EP-'endpoint'. Function takes care of NAKS. + if (rcode == hrTOGERR) { + // yes, we flip it wrong here so that next time it is actually correct! + pep->bmRcvToggle = (regRd(rHRSL) & bmRCVTOGRD) ? 0 : 1; + regWr(rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0); //set toggle value + continue; + } + if (rcode) { + //printf(">>>>>>>> Problem! dispatchPkt %2.2x\r\n", rcode); + break; //should be 0, indicating ACK. Else return error code. + } + /* check for RCVDAVIRQ and generate error if not present */ + /* the only case when absence of RCVDAVIRQ makes sense is when toggle error occurred. Need to add handling for that */ + if ((regRd(rHIRQ) & bmRCVDAVIRQ) == 0) { + //printf(">>>>>>>> Problem! NO RCVDAVIRQ!\r\n"); + rcode = 0xF0; //receive error + break; + } + pktsize = regRd(rRCVBC); //number of received bytes + //printf("Got %i bytes \r\n", pktsize); + // This would be OK, but... + //assert(pktsize <= nbytes); + if (pktsize > nbytes) { + // This can happen. Use of assert on Arduino locks up the Arduino. + // So I will trim the value, and hope for the best. + //printf(">>>>>>>> Problem! Wanted %i bytes but got %i.\r\n", nbytes, pktsize); + pktsize = nbytes; + } + + int16_t mem_left = (int16_t)nbytes - *((int16_t*)nbytesptr); + if (mem_left < 0) mem_left = 0; + + data = bytesRd(rRCVFIFO, ((pktsize > mem_left) ? mem_left : pktsize), data); + + regWr(rHIRQ, bmRCVDAVIRQ); // Clear the IRQ & free the buffer + *nbytesptr += pktsize; // add this packet's byte count to total transfer length + + /* The transfer is complete under two conditions: */ + /* 1. The device sent a short packet (L.T. maxPacketSize) */ + /* 2. 'nbytes' have been transferred. */ + if (pktsize < maxpktsize || *nbytesptr >= nbytes) { // Transferred 'nbytes' bytes? + // Save toggle value + pep->bmRcvToggle = ((regRd(rHRSL) & bmRCVTOGRD)) ? 1 : 0; + //printf("\r\n"); + rcode = 0; + break; + } + else if (bInterval > 0) + delay(bInterval); // Delay according to polling interval + } + return rcode; } /* OUT transfer to arbitrary endpoint. Handles multiple packets if necessary. Transfers 'nbytes' bytes. */ @@ -303,336 +289,324 @@ uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, ui /* rcode 0 if no errors. rcode 01-0f is relayed from HRSL */ uint8_t USB::outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* data) { - EpInfo *pep = NULL; - uint16_t nak_limit = 0; + EpInfo *pep = NULL; + uint16_t nak_limit = 0; - uint8_t rcode = SetAddress(addr, ep, &pep, &nak_limit); + uint8_t rcode = SetAddress(addr, ep, &pep, &nak_limit); + if (rcode) return rcode; - if(rcode) - return rcode; - - return OutTransfer(pep, nak_limit, nbytes, data); + return OutTransfer(pep, nak_limit, nbytes, data); } uint8_t USB::OutTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8_t *data) { - uint8_t rcode = hrSUCCESS, retry_count; - uint8_t *data_p = data; //local copy of the data pointer - uint16_t bytes_tosend, nak_count; - uint16_t bytes_left = nbytes; - - uint8_t maxpktsize = pep->maxPktSize; - - if(maxpktsize < 1 || maxpktsize > 64) - return USB_ERROR_INVALID_MAX_PKT_SIZE; - - uint32_t timeout = (uint32_t)millis() + USB_XFER_TIMEOUT; - - regWr(rHCTL, (pep->bmSndToggle) ? bmSNDTOG1 : bmSNDTOG0); //set toggle value - - while(bytes_left) { - retry_count = 0; - nak_count = 0; - bytes_tosend = (bytes_left >= maxpktsize) ? maxpktsize : bytes_left; - bytesWr(rSNDFIFO, bytes_tosend, data_p); //filling output FIFO - regWr(rSNDBC, bytes_tosend); //set number of bytes - regWr(rHXFR, (tokOUT | pep->epAddr)); //dispatch packet - while(!(regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ - regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ - rcode = (regRd(rHRSL) & 0x0f); - - while(rcode && ((int32_t)((uint32_t)millis() - timeout) < 0L)) { - switch(rcode) { - case hrNAK: - nak_count++; - if(nak_limit && (nak_count == nak_limit)) - goto breakout; - //return ( rcode); - break; - case hrTIMEOUT: - retry_count++; - if(retry_count == USB_RETRY_LIMIT) - goto breakout; - //return ( rcode); - break; - case hrTOGERR: - // yes, we flip it wrong here so that next time it is actually correct! - pep->bmSndToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1; - regWr(rHCTL, (pep->bmSndToggle) ? bmSNDTOG1 : bmSNDTOG0); //set toggle value - break; - default: - goto breakout; - }//switch( rcode - - /* process NAK according to Host out NAK bug */ - regWr(rSNDBC, 0); - regWr(rSNDFIFO, *data_p); - regWr(rSNDBC, bytes_tosend); - regWr(rHXFR, (tokOUT | pep->epAddr)); //dispatch packet - while(!(regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ - regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ - rcode = (regRd(rHRSL) & 0x0f); - }//while( rcode && .... - bytes_left -= bytes_tosend; - data_p += bytes_tosend; - }//while( bytes_left... + uint8_t rcode = hrSUCCESS, retry_count; + uint8_t *data_p = data; //local copy of the data pointer + uint16_t bytes_tosend, nak_count; + uint16_t bytes_left = nbytes; + + uint8_t maxpktsize = pep->maxPktSize; + + if (maxpktsize < 1 || maxpktsize > 64) + return USB_ERROR_INVALID_MAX_PKT_SIZE; + + uint32_t timeout = (uint32_t)millis() + USB_XFER_TIMEOUT; + + regWr(rHCTL, (pep->bmSndToggle) ? bmSNDTOG1 : bmSNDTOG0); //set toggle value + + while (bytes_left) { + retry_count = 0; + nak_count = 0; + bytes_tosend = (bytes_left >= maxpktsize) ? maxpktsize : bytes_left; + bytesWr(rSNDFIFO, bytes_tosend, data_p); //filling output FIFO + regWr(rSNDBC, bytes_tosend); //set number of bytes + regWr(rHXFR, (tokOUT | pep->epAddr)); //dispatch packet + while (!(regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ + regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ + rcode = (regRd(rHRSL) & 0x0F); + + while (rcode && ((int32_t)((uint32_t)millis() - timeout) < 0L)) { + switch (rcode) { + case hrNAK: + nak_count++; + if (nak_limit && (nak_count == nak_limit)) + goto breakout; + //return ( rcode); + break; + case hrTIMEOUT: + retry_count++; + if (retry_count == USB_RETRY_LIMIT) + goto breakout; + //return ( rcode); + break; + case hrTOGERR: + // yes, we flip it wrong here so that next time it is actually correct! + pep->bmSndToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1; + regWr(rHCTL, (pep->bmSndToggle) ? bmSNDTOG1 : bmSNDTOG0); //set toggle value + break; + default: + goto breakout; + } + + /* process NAK according to Host out NAK bug */ + regWr(rSNDBC, 0); + regWr(rSNDFIFO, *data_p); + regWr(rSNDBC, bytes_tosend); + regWr(rHXFR, (tokOUT | pep->epAddr)); //dispatch packet + while (!(regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ + regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ + rcode = (regRd(rHRSL) & 0x0F); + } // while rcode && .... + bytes_left -= bytes_tosend; + data_p += bytes_tosend; + } // while bytes_left... breakout: - pep->bmSndToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 1 : 0; //bmSNDTOG1 : bmSNDTOG0; //update toggle - return ( rcode); //should be 0 in all cases + pep->bmSndToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 1 : 0; //bmSNDTOG1 : bmSNDTOG0; //update toggle + return ( rcode); //should be 0 in all cases } + /* dispatch USB packet. Assumes peripheral address is set and relevant buffer is loaded/empty */ /* If NAK, tries to re-send up to nak_limit times */ /* If nak_limit == 0, do not count NAKs, exit after timeout */ /* If bus timeout, re-sends up to USB_RETRY_LIMIT times */ -/* return codes 0x00-0x0f are HRSLT( 0x00 being success ), 0xff means timeout */ +/* return codes 0x00-0x0F are HRSLT( 0x00 being success ), 0xFF means timeout */ uint8_t USB::dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit) { - uint32_t timeout = (uint32_t)millis() + USB_XFER_TIMEOUT; - uint8_t tmpdata; - uint8_t rcode = hrSUCCESS; - uint8_t retry_count = 0; - uint16_t nak_count = 0; - - while((int32_t)((uint32_t)millis() - timeout) < 0L) { -#if defined(ESP8266) || defined(ESP32) - yield(); // needed in order to reset the watchdog timer on the ESP8266 -#endif - regWr(rHXFR, (token | ep)); //launch the transfer - rcode = USB_ERROR_TRANSFER_TIMEOUT; - - while((int32_t)((uint32_t)millis() - timeout) < 0L) //wait for transfer completion - { -#if defined(ESP8266) || defined(ESP32) - yield(); // needed in order to reset the watchdog timer on the ESP8266 -#endif - tmpdata = regRd(rHIRQ); - - if(tmpdata & bmHXFRDNIRQ) { - regWr(rHIRQ, bmHXFRDNIRQ); //clear the interrupt - rcode = 0x00; - break; - }//if( tmpdata & bmHXFRDNIRQ - - }//while ( millis() < timeout - - //if (rcode != 0x00) //exit if timeout - // return ( rcode); - - rcode = (regRd(rHRSL) & 0x0f); //analyze transfer result - - switch(rcode) { - case hrNAK: - nak_count++; - if(nak_limit && (nak_count == nak_limit)) - return (rcode); - break; - case hrTIMEOUT: - retry_count++; - if(retry_count == USB_RETRY_LIMIT) - return (rcode); - break; - default: - return (rcode); - }//switch( rcode - - }//while( timeout > millis() - return ( rcode); + uint32_t timeout = (uint32_t)millis() + USB_XFER_TIMEOUT; + uint8_t tmpdata; + uint8_t rcode = hrSUCCESS; + uint8_t retry_count = 0; + uint16_t nak_count = 0; + + while ((int32_t)((uint32_t)millis() - timeout) < 0L) { + #if defined(ESP8266) || defined(ESP32) + yield(); // needed in order to reset the watchdog timer on the ESP8266 + #endif + regWr(rHXFR, (token | ep)); //launch the transfer + rcode = USB_ERROR_TRANSFER_TIMEOUT; + + while ((int32_t)((uint32_t)millis() - timeout) < 0L) { //wait for transfer completion + #if defined(ESP8266) || defined(ESP32) + yield(); // needed to reset the watchdog timer on the ESP8266 + #endif + tmpdata = regRd(rHIRQ); + + if (tmpdata & bmHXFRDNIRQ) { + regWr(rHIRQ, bmHXFRDNIRQ); //clear the interrupt + rcode = 0x00; + break; + } + + } // while millis() < timeout + + //if (rcode != 0x00) //exit if timeout + // return ( rcode); + + rcode = (regRd(rHRSL) & 0x0F); //analyze transfer result + + switch (rcode) { + case hrNAK: + nak_count++; + if (nak_limit && (nak_count == nak_limit)) + return (rcode); + break; + case hrTIMEOUT: + retry_count++; + if (retry_count == USB_RETRY_LIMIT) + return (rcode); + break; + default: + return (rcode); + } + + } // while timeout > millis() + return rcode; } /* USB main task. Performs enumeration/cleanup */ -void USB::Task(void) //USB state machine -{ - uint8_t rcode; - uint8_t tmpdata; - static uint32_t delay = 0; - //USB_DEVICE_DESCRIPTOR buf; - bool lowspeed = false; - - MAX3421E::Task(); - - tmpdata = getVbusState(); - - /* modify USB task state if Vbus changed */ - switch(tmpdata) { - case SE1: //illegal state - usb_task_state = USB_DETACHED_SUBSTATE_ILLEGAL; - lowspeed = false; - break; - case SE0: //disconnected - if((usb_task_state & USB_STATE_MASK) != USB_STATE_DETACHED) - usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE; - lowspeed = false; - break; - case LSHOST: - - lowspeed = true; - //intentional fallthrough - case FSHOST: //attached - if((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) { - delay = (uint32_t)millis() + USB_SETTLE_DELAY; - usb_task_state = USB_ATTACHED_SUBSTATE_SETTLE; - } - break; - }// switch( tmpdata - - for(uint8_t i = 0; i < USB_NUMDEVICES; i++) - if(devConfig[i]) - rcode = devConfig[i]->Poll(); - - switch(usb_task_state) { - case USB_DETACHED_SUBSTATE_INITIALIZE: - init(); - - for(uint8_t i = 0; i < USB_NUMDEVICES; i++) - if(devConfig[i]) - rcode = devConfig[i]->Release(); - - usb_task_state = USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE; - break; - case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE: //just sit here - break; - case USB_DETACHED_SUBSTATE_ILLEGAL: //just sit here - break; - case USB_ATTACHED_SUBSTATE_SETTLE: //settle time for just attached device - if((int32_t)((uint32_t)millis() - delay) >= 0L) - usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE; - else break; // don't fall through - case USB_ATTACHED_SUBSTATE_RESET_DEVICE: - regWr(rHCTL, bmBUSRST); //issue bus reset - usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE; - break; - case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE: - if((regRd(rHCTL) & bmBUSRST) == 0) { - tmpdata = regRd(rMODE) | bmSOFKAENAB; //start SOF generation - regWr(rMODE, tmpdata); - usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF; - //delay = (uint32_t)millis() + 20; //20ms wait after reset per USB spec - } - break; - case USB_ATTACHED_SUBSTATE_WAIT_SOF: //todo: change check order - if(regRd(rHIRQ) & bmFRAMEIRQ) { - //when first SOF received _and_ 20ms has passed we can continue - /* - if (delay < (uint32_t)millis()) //20ms passed - usb_task_state = USB_STATE_CONFIGURING; - */ - usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET; - delay = (uint32_t)millis() + 20; - } - break; - case USB_ATTACHED_SUBSTATE_WAIT_RESET: - if((int32_t)((uint32_t)millis() - delay) >= 0L) usb_task_state = USB_STATE_CONFIGURING; - else break; // don't fall through - case USB_STATE_CONFIGURING: - - //Serial.print("\r\nConf.LS: "); - //Serial.println(lowspeed, HEX); - - rcode = Configuring(0, 0, lowspeed); - - if(rcode) { - if(rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE) { - usb_error = rcode; - usb_task_state = USB_STATE_ERROR; - } - } else - usb_task_state = USB_STATE_RUNNING; - break; - case USB_STATE_RUNNING: - break; - case USB_STATE_ERROR: - //MAX3421E::Init(); - break; - } // switch( usb_task_state ) +void USB::Task(void) { //USB state machine + uint8_t rcode; + uint8_t tmpdata; + static uint32_t delay = 0; + //USB_DEVICE_DESCRIPTOR buf; + bool lowspeed = false; + + MAX3421E::Task(); + + tmpdata = getVbusState(); + + /* modify USB task state if Vbus changed */ + switch (tmpdata) { + case SE1: //illegal state + usb_task_state = USB_DETACHED_SUBSTATE_ILLEGAL; + lowspeed = false; + break; + case SE0: //disconnected + if ((usb_task_state & USB_STATE_MASK) != USB_STATE_DETACHED) + usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE; + lowspeed = false; + break; + case LSHOST: + lowspeed = true; + //intentional fallthrough + case FSHOST: //attached + if ((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) { + delay = (uint32_t)millis() + USB_SETTLE_DELAY; + usb_task_state = USB_ATTACHED_SUBSTATE_SETTLE; + } + break; + } + + for (uint8_t i = 0; i < USB_NUMDEVICES; i++) + if (devConfig[i]) rcode = devConfig[i]->Poll(); + + switch (usb_task_state) { + case USB_DETACHED_SUBSTATE_INITIALIZE: + init(); + + for (uint8_t i = 0; i < USB_NUMDEVICES; i++) + if (devConfig[i]) + rcode = devConfig[i]->Release(); + + usb_task_state = USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE; + break; + case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE: //just sit here + break; + case USB_DETACHED_SUBSTATE_ILLEGAL: //just sit here + break; + case USB_ATTACHED_SUBSTATE_SETTLE: //settle time for just attached device + if ((int32_t)((uint32_t)millis() - delay) >= 0L) + usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE; + else break; // don't fall through + case USB_ATTACHED_SUBSTATE_RESET_DEVICE: + regWr(rHCTL, bmBUSRST); //issue bus reset + usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE; + break; + case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE: + if ((regRd(rHCTL) & bmBUSRST) == 0) { + tmpdata = regRd(rMODE) | bmSOFKAENAB; //start SOF generation + regWr(rMODE, tmpdata); + usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF; + //delay = (uint32_t)millis() + 20; //20ms wait after reset per USB spec + } + break; + case USB_ATTACHED_SUBSTATE_WAIT_SOF: //todo: change check order + if (regRd(rHIRQ) & bmFRAMEIRQ) { + //when first SOF received _and_ 20ms has passed we can continue + /* + if (delay < (uint32_t)millis()) //20ms passed + usb_task_state = USB_STATE_CONFIGURING; + */ + usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET; + delay = (uint32_t)millis() + 20; + } + break; + case USB_ATTACHED_SUBSTATE_WAIT_RESET: + if ((int32_t)((uint32_t)millis() - delay) >= 0L) usb_task_state = USB_STATE_CONFIGURING; + else break; // don't fall through + case USB_STATE_CONFIGURING: + + //Serial.print("\r\nConf.LS: "); + //Serial.println(lowspeed, HEX); + + rcode = Configuring(0, 0, lowspeed); + + if (!rcode) + usb_task_state = USB_STATE_RUNNING; + else if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE) { + usb_error = rcode; + usb_task_state = USB_STATE_ERROR; + } + break; + case USB_STATE_RUNNING: + break; + case USB_STATE_ERROR: + //MAX3421E::Init(); + break; + } } uint8_t USB::DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed) { - //uint8_t buf[12]; - uint8_t rcode; - UsbDevice *p0 = NULL, *p = NULL; - - // Get pointer to pseudo device with address 0 assigned - p0 = addrPool.GetUsbDevicePtr(0); - - if(!p0) - return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; - - if(!p0->epinfo) - return USB_ERROR_EPINFO_IS_NULL; - - p0->lowspeed = (lowspeed) ? true : false; + //uint8_t buf[12]; + uint8_t rcode; + UsbDevice *p0 = NULL, *p = NULL; - // Allocate new address according to device class - uint8_t bAddress = addrPool.AllocAddress(parent, false, port); + // Get pointer to pseudo device with address 0 assigned + p0 = addrPool.GetUsbDevicePtr(0); + if (!p0) return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; + if (!p0->epinfo) return USB_ERROR_EPINFO_IS_NULL; - if(!bAddress) - return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; + p0->lowspeed = lowspeed; - p = addrPool.GetUsbDevicePtr(bAddress); + // Allocate new address according to device class + uint8_t bAddress = addrPool.AllocAddress(parent, false, port); + if (!bAddress) return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; - if(!p) - return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; + p = addrPool.GetUsbDevicePtr(bAddress); + if (!p) return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; - p->lowspeed = lowspeed; + p->lowspeed = lowspeed; - // Assign new address to the device - rcode = setAddr(0, 0, bAddress); - - if(rcode) { - addrPool.FreeAddress(bAddress); - bAddress = 0; - return rcode; - } - return 0; -}; + // Assign new address to the device + rcode = setAddr(0, 0, bAddress); + if (rcode) { + addrPool.FreeAddress(bAddress); + bAddress = 0; + } + return rcode; +} uint8_t USB::AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lowspeed) { - //printf("AttemptConfig: parent = %i, port = %i\r\n", parent, port); - uint8_t retries = 0; + //printf("AttemptConfig: parent = %i, port = %i\r\n", parent, port); + uint8_t retries = 0; again: - uint8_t rcode = devConfig[driver]->ConfigureDevice(parent, port, lowspeed); - if(rcode == USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET) { - if(parent == 0) { - // Send a bus reset on the root interface. - regWr(rHCTL, bmBUSRST); //issue bus reset - delay(102); // delay 102ms, compensate for clock inaccuracy. - } else { - // reset parent port - devConfig[parent]->ResetHubPort(port); - } - } else if(rcode == hrJERR && retries < 3) { // Some devices returns this when plugged in - trying to initialize the device again usually works - delay(100); - retries++; - goto again; - } else if(rcode) - return rcode; - - rcode = devConfig[driver]->Init(parent, port, lowspeed); - if(rcode == hrJERR && retries < 3) { // Some devices returns this when plugged in - trying to initialize the device again usually works - delay(100); - retries++; - goto again; - } - if(rcode) { - // Issue a bus reset, because the device may be in a limbo state - if(parent == 0) { - // Send a bus reset on the root interface. - regWr(rHCTL, bmBUSRST); //issue bus reset - delay(102); // delay 102ms, compensate for clock inaccuracy. - } else { - // reset parent port - devConfig[parent]->ResetHubPort(port); - } - } - return rcode; + uint8_t rcode = devConfig[driver]->ConfigureDevice(parent, port, lowspeed); + if (rcode == USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET) { + if (parent == 0) { + // Send a bus reset on the root interface. + regWr(rHCTL, bmBUSRST); //issue bus reset + delay(102); // delay 102ms, compensate for clock inaccuracy. + } + else { + // reset parent port + devConfig[parent]->ResetHubPort(port); + } + } + else if (rcode == hrJERR && retries < 3) { // Some devices returns this when plugged in - trying to initialize the device again usually works + delay(100); + retries++; + goto again; + } + else if (rcode) + return rcode; + + rcode = devConfig[driver]->Init(parent, port, lowspeed); + if (rcode == hrJERR && retries < 3) { // Some devices returns this when plugged in - trying to initialize the device again usually works + delay(100); + retries++; + goto again; + } + + if (rcode) { + // Issue a bus reset, because the device may be in a limbo state + if (parent == 0) { + // Send a bus reset on the root interface. + regWr(rHCTL, bmBUSRST); //issue bus reset + delay(102); // delay 102ms, compensate for clock inaccuracy. + } + else { + // reset parent port + devConfig[parent]->ResetHubPort(port); + } + } + return rcode; } -/* - * This is broken. We need to enumerate differently. +/** + * This is broken. It needs to enumerate differently. * It causes major problems with several devices if detected in an unexpected order. * - * * Oleg - I wouldn't do anything before the newly connected device is considered sane. * i.e.(delays are not indicated for brevity): * 1. reset @@ -649,7 +623,7 @@ again: * 4: set address * 5: pUsb->setEpInfoEntry(bAddress, 1, epInfo), exit on fail * 6: while (configurations) { - * for(each configuration) { + * for (each configuration) { * for (each driver) { * 6a: Ask device if it likes configuration. Returns 0 on OK. * If successful, the driver configured device. @@ -663,170 +637,161 @@ again: * } * } * } - * 7: for(each driver) { + * 7: for (each driver) { * 7a: Ask device if it knows this VID/PID. Acts exactly like 6a, but using VID/PID * 8: if we get here, no driver likes the device plugged in, so exit failure. * */ uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) { - //uint8_t bAddress = 0; - //printf("Configuring: parent = %i, port = %i\r\n", parent, port); - uint8_t devConfigIndex; - uint8_t rcode = 0; - uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)]; - USB_DEVICE_DESCRIPTOR *udd = reinterpret_cast(buf); - UsbDevice *p = NULL; - EpInfo *oldep_ptr = NULL; - EpInfo epInfo; - - epInfo.epAddr = 0; - epInfo.maxPktSize = 8; - epInfo.bmSndToggle = 0; - epInfo.bmRcvToggle = 0; - epInfo.bmNakPower = USB_NAK_MAX_POWER; - - //delay(2000); - AddressPool &addrPool = GetAddressPool(); - // Get pointer to pseudo device with address 0 assigned - p = addrPool.GetUsbDevicePtr(0); - if(!p) { - //printf("Configuring error: USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL\r\n"); - return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; - } - - // Save old pointer to EP_RECORD of address 0 - oldep_ptr = p->epinfo; - - // Temporary assign new pointer to epInfo to p->epinfo in order to - // avoid toggle inconsistence - - p->epinfo = &epInfo; - - p->lowspeed = lowspeed; - // Get device descriptor - rcode = getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); - - // Restore p->epinfo - p->epinfo = oldep_ptr; - - if(rcode) { - //printf("Configuring error: Can't get USB_DEVICE_DESCRIPTOR\r\n"); - return rcode; - } - - // to-do? - // Allocate new address according to device class - //bAddress = addrPool.AllocAddress(parent, false, port); - - uint16_t vid = udd->idVendor; - uint16_t pid = udd->idProduct; - uint8_t klass = udd->bDeviceClass; - uint8_t subklass = udd->bDeviceSubClass; - // Attempt to configure if VID/PID or device class matches with a driver - // Qualify with subclass too. - // - // VID/PID & class tests default to false for drivers not yet ported - // subclass defaults to true, so you don't have to define it if you don't have to. - // - for(devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) { - if(!devConfig[devConfigIndex]) continue; // no driver - if(devConfig[devConfigIndex]->GetAddress()) continue; // consumed - if(devConfig[devConfigIndex]->DEVSUBCLASSOK(subklass) && (devConfig[devConfigIndex]->VIDPIDOK(vid, pid) || devConfig[devConfigIndex]->DEVCLASSOK(klass))) { - rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed); - if(rcode != USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED) - break; - } - } - - if(devConfigIndex < USB_NUMDEVICES) { - return rcode; - } - - - // blindly attempt to configure - for(devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) { - if(!devConfig[devConfigIndex]) continue; - if(devConfig[devConfigIndex]->GetAddress()) continue; // consumed - if(devConfig[devConfigIndex]->DEVSUBCLASSOK(subklass) && (devConfig[devConfigIndex]->VIDPIDOK(vid, pid) || devConfig[devConfigIndex]->DEVCLASSOK(klass))) continue; // If this is true it means it must have returned USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED above - rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed); - - //printf("ERROR ENUMERATING %2.2x\r\n", rcode); - if(!(rcode == USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED || rcode == USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE)) { - // in case of an error dev_index should be reset to 0 - // in order to start from the very beginning the - // next time the program gets here - //if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE) - // devConfigIndex = 0; - return rcode; - } - } - // if we get here that means that the device class is not supported by any of registered classes - rcode = DefaultAddressing(parent, port, lowspeed); - - return rcode; + //uint8_t bAddress = 0; + //printf("Configuring: parent = %i, port = %i\r\n", parent, port); + uint8_t devConfigIndex; + uint8_t rcode = 0; + uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)]; + USB_DEVICE_DESCRIPTOR *udd = reinterpret_cast(buf); + UsbDevice *p = NULL; + EpInfo *oldep_ptr = NULL; + EpInfo epInfo; + + epInfo.epAddr = 0; + epInfo.maxPktSize = 8; + epInfo.bmSndToggle = 0; + epInfo.bmRcvToggle = 0; + epInfo.bmNakPower = USB_NAK_MAX_POWER; + + //delay(2000); + AddressPool &addrPool = GetAddressPool(); + // Get pointer to pseudo device with address 0 assigned + p = addrPool.GetUsbDevicePtr(0); + if (!p) { + //printf("Configuring error: USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL\r\n"); + return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; + } + + // Save old pointer to EP_RECORD of address 0 + oldep_ptr = p->epinfo; + + // Temporary assign new pointer to epInfo to p->epinfo in order to + // avoid toggle inconsistence + + p->epinfo = &epInfo; + + p->lowspeed = lowspeed; + // Get device descriptor + rcode = getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); + + // Restore p->epinfo + p->epinfo = oldep_ptr; + + if (rcode) { + //printf("Configuring error: Can't get USB_DEVICE_DESCRIPTOR\r\n"); + return rcode; + } + + // to-do? + // Allocate new address according to device class + //bAddress = addrPool.AllocAddress(parent, false, port); + + uint16_t vid = udd->idVendor, pid = udd->idProduct; + uint8_t klass = udd->bDeviceClass, subklass = udd->bDeviceSubClass; + + // Attempt to configure if VID/PID or device class matches with a driver + // Qualify with subclass too. + // + // VID/PID & class tests default to false for drivers not yet ported + // subclass defaults to true, so you don't have to define it if you don't have to. + // + for (devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) { + if (!devConfig[devConfigIndex]) continue; // no driver + if (devConfig[devConfigIndex]->GetAddress()) continue; // consumed + if (devConfig[devConfigIndex]->DEVSUBCLASSOK(subklass) && (devConfig[devConfigIndex]->VIDPIDOK(vid, pid) || devConfig[devConfigIndex]->DEVCLASSOK(klass))) { + rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed); + if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED) + break; + } + } + + if (devConfigIndex < USB_NUMDEVICES) return rcode; + + // blindly attempt to configure + for (devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) { + if (!devConfig[devConfigIndex]) continue; + if (devConfig[devConfigIndex]->GetAddress()) continue; // consumed + if (devConfig[devConfigIndex]->DEVSUBCLASSOK(subklass) && (devConfig[devConfigIndex]->VIDPIDOK(vid, pid) || devConfig[devConfigIndex]->DEVCLASSOK(klass))) continue; // If this is true it means it must have returned USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED above + rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed); + + //printf("ERROR ENUMERATING %2.2x\r\n", rcode); + if (!(rcode == USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED || rcode == USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE)) { + // in case of an error dev_index should be reset to 0 + // in order to start from the very beginning the + // next time the program gets here + //if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE) + // devConfigIndex = 0; + return rcode; + } + } + // Arriving here means the device class is unsupported by registered classes + return DefaultAddressing(parent, port, lowspeed); } uint8_t USB::ReleaseDevice(uint8_t addr) { - if(!addr) - return 0; - - for(uint8_t i = 0; i < USB_NUMDEVICES; i++) { - if(!devConfig[i]) continue; - if(devConfig[i]->GetAddress() == addr) - return devConfig[i]->Release(); - } - return 0; + if (addr) { + for (uint8_t i = 0; i < USB_NUMDEVICES; i++) { + if (!devConfig[i]) continue; + if (devConfig[i]->GetAddress() == addr) + return devConfig[i]->Release(); + } + } + return 0; } #if 1 //!defined(USB_METHODS_INLINE) //get device descriptor uint8_t USB::getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr) { - return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, nbytes, dataptr, NULL)); + return ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, nbytes, dataptr, NULL); } //get configuration descriptor uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t* dataptr) { - return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, nbytes, dataptr, NULL)); + return ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, nbytes, dataptr, NULL); } /* Requests Configuration Descriptor. Sends two Get Conf Descr requests. The first one gets the total length of all descriptors, then the second one requests this total length. The length of the first request can be shorter ( 4 bytes ), however, there are devices which won't work unless this length is set to 9 */ uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint8_t conf, USBReadParser *p) { - const uint8_t bufSize = 64; - uint8_t buf[bufSize]; - USB_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast(buf); - - uint8_t ret = getConfDescr(addr, ep, 9, conf, buf); + const uint8_t bufSize = 64; + uint8_t buf[bufSize]; + USB_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast(buf); - if(ret) - return ret; + uint8_t ret = getConfDescr(addr, ep, 9, conf, buf); + if (ret) return ret; - uint16_t total = ucd->wTotalLength; + uint16_t total = ucd->wTotalLength; - //USBTRACE2("\r\ntotal conf.size:", total); + //USBTRACE2("\r\ntotal conf.size:", total); - return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, total, bufSize, buf, p)); + return ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, total, bufSize, buf, p); } //get string descriptor uint8_t USB::getStrDescr(uint8_t addr, uint8_t ep, uint16_t ns, uint8_t index, uint16_t langid, uint8_t* dataptr) { - return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, ns, ns, dataptr, NULL)); + return ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, ns, ns, dataptr, NULL); } //set address uint8_t USB::setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr) { - uint8_t rcode = ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL); - //delay(2); //per USB 2.0 sect.9.2.6.3 - delay(300); // Older spec says you should wait at least 200ms - return rcode; - //return ( ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL)); + uint8_t rcode = ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL); + //delay(2); //per USB 2.0 sect.9.2.6.3 + delay(300); // Older spec says you should wait at least 200ms + return rcode; + //return ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL); } //set configuration uint8_t USB::setConf(uint8_t addr, uint8_t ep, uint8_t conf_value) { - return ( ctrlReq(addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL)); + return ctrlReq(addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL); } #endif // defined(USB_METHODS_INLINE) diff --git a/Marlin/src/sd/usb_flashdrive/lib/Usb.h b/Marlin/src/sd/usb_flashdrive/lib/Usb.h index 662c11a4f..5880f9de0 100644 --- a/Marlin/src/sd/usb_flashdrive/lib/Usb.h +++ b/Marlin/src/sd/usb_flashdrive/lib/Usb.h @@ -22,8 +22,9 @@ * Web : http://www.circuitsathome.com * e-mail : support@circuitsathome.com */ +#pragma once + /* USB functions */ -#ifndef _usb_h_ #define _usb_h_ #include "../../../inc/MarlinConfigPre.h" @@ -50,4 +51,4 @@ #include "parsetools.h" #include "confdescparser.h" -#endif //_usb_h_ +#undef _usb_h_ diff --git a/Marlin/src/sd/usb_flashdrive/lib/UsbCore.h b/Marlin/src/sd/usb_flashdrive/lib/UsbCore.h index 14e1261d7..06443ffcd 100644 --- a/Marlin/src/sd/usb_flashdrive/lib/UsbCore.h +++ b/Marlin/src/sd/usb_flashdrive/lib/UsbCore.h @@ -231,8 +231,8 @@ public: }; uint8_t RegisterDeviceClass(USBDeviceConfig *pdev) { - for(uint8_t i = 0; i < USB_NUMDEVICES; i++) { - if(!devConfig[i]) { + for (uint8_t i = 0; i < USB_NUMDEVICES; i++) { + if (!devConfig[i]) { devConfig[i] = pdev; return 0; } diff --git a/Marlin/src/sd/usb_flashdrive/lib/address.h b/Marlin/src/sd/usb_flashdrive/lib/address.h index 6a40eb877..d55d896cc 100644 --- a/Marlin/src/sd/usb_flashdrive/lib/address.h +++ b/Marlin/src/sd/usb_flashdrive/lib/address.h @@ -22,13 +22,11 @@ * Web : http://www.circuitsathome.com * e-mail : support@circuitsathome.com */ +#pragma once -#if !defined(_usb_h_) || defined(__ADDRESS_H__) -#error "Never include address.h directly; include Usb.h instead" -#else -#define __ADDRESS_H__ - - +#ifndef _usb_h_ + #error "Never include address.h directly; include Usb.h instead" +#endif /* NAK powers. To save space in endpoint data structure, amount of retries before giving up and returning 0x4 is stored in */ /* bmNakPower as a power of 2. The actual nak_limit is then calculated as nak_limit = ( 2^bmNakPower - 1) */ @@ -38,18 +36,18 @@ #define USB_NAK_NONAK 0 //Do not count NAKs, stop retrying after USB Timeout struct EpInfo { - uint8_t epAddr; // Endpoint address - uint8_t maxPktSize; // Maximum packet size - - union { - uint8_t epAttribs; - - struct { - uint8_t bmSndToggle : 1; // Send toggle, when zero bmSNDTOG0, bmSNDTOG1 otherwise - uint8_t bmRcvToggle : 1; // Send toggle, when zero bmRCVTOG0, bmRCVTOG1 otherwise - uint8_t bmNakPower : 6; // Binary order for NAK_LIMIT value - } __attribute__((packed)); - }; + uint8_t epAddr; // Endpoint address + uint8_t maxPktSize; // Maximum packet size + + union { + uint8_t epAttribs; + + struct { + uint8_t bmSndToggle : 1; // Send toggle, when zero bmSNDTOG0, bmSNDTOG1 otherwise + uint8_t bmRcvToggle : 1; // Send toggle, when zero bmRCVTOG0, bmRCVTOG1 otherwise + uint8_t bmNakPower : 6; // Binary order for NAK_LIMIT value + } __attribute__((packed)); + }; } __attribute__((packed)); // 7 6 5 4 3 2 1 0 @@ -63,17 +61,15 @@ struct EpInfo { // struct UsbDeviceAddress { - - union { - - struct { - uint8_t bmAddress : 3; // device address/port number - uint8_t bmParent : 3; // parent hub address - uint8_t bmHub : 1; // hub flag - uint8_t bmReserved : 1; // reserved, must be zero - } __attribute__((packed)); - uint8_t devAddress; - }; + union { + struct { + uint8_t bmAddress : 3; // device address/port number + uint8_t bmParent : 3; // parent hub address + uint8_t bmHub : 1; // hub flag + uint8_t bmReserved : 1; // reserved, must be zero + } __attribute__((packed)); + uint8_t devAddress; + }; } __attribute__((packed)); #define bmUSB_DEV_ADDR_ADDRESS 0x07 @@ -81,18 +77,18 @@ struct UsbDeviceAddress { #define bmUSB_DEV_ADDR_HUB 0x40 struct UsbDevice { - EpInfo *epinfo; // endpoint info pointer - UsbDeviceAddress address; - uint8_t epcount; // number of endpoints - bool lowspeed; // indicates if a device is the low speed one - // uint8_t devclass; // device class + EpInfo *epinfo; // endpoint info pointer + UsbDeviceAddress address; + uint8_t epcount; // number of endpoints + bool lowspeed; // indicates if a device is the low speed one + // uint8_t devclass; // device class } __attribute__((packed)); class AddressPool { -public: - virtual UsbDevice* GetUsbDevicePtr(uint8_t addr) = 0; - virtual uint8_t AllocAddress(uint8_t parent, bool is_hub = false, uint8_t port = 0) = 0; - virtual void FreeAddress(uint8_t addr) = 0; + public: + virtual UsbDevice* GetUsbDevicePtr(uint8_t addr) = 0; + virtual uint8_t AllocAddress(uint8_t parent, bool is_hub = false, uint8_t port = 0) = 0; + virtual void FreeAddress(uint8_t addr) = 0; }; typedef void (*UsbDeviceHandleFunc)(UsbDevice *pdev); @@ -102,190 +98,174 @@ typedef void (*UsbDeviceHandleFunc)(UsbDevice *pdev); template class AddressPoolImpl : public AddressPool { - EpInfo dev0ep; //Endpoint data structure used during enumeration for uninitialized device + EpInfo dev0ep; //Endpoint data structure used during enumeration for uninitialized device + + uint8_t hubCounter; // hub counter is kept + // in order to avoid hub address duplication - uint8_t hubCounter; // hub counter is kept - // in order to avoid hub address duplication + UsbDevice thePool[MAX_DEVICES_ALLOWED]; - UsbDevice thePool[MAX_DEVICES_ALLOWED]; + // Initialize address pool entry - // Initializes address pool entry + void InitEntry(uint8_t index) { + thePool[index].address.devAddress = 0; + thePool[index].epcount = 1; + thePool[index].lowspeed = 0; + thePool[index].epinfo = &dev0ep; + } - void InitEntry(uint8_t index) { - thePool[index].address.devAddress = 0; - thePool[index].epcount = 1; - thePool[index].lowspeed = 0; - thePool[index].epinfo = &dev0ep; - }; + // Return thePool index for a given address - // Returns thePool index for a given address + uint8_t FindAddressIndex(uint8_t address = 0) { + for (uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++) + if (thePool[i].address.devAddress == address) + return i; - uint8_t FindAddressIndex(uint8_t address = 0) { - for(uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++) { - if(thePool[i].address.devAddress == address) - return i; - } - return 0; - }; + return 0; + } - // Returns thePool child index for a given parent + // Return thePool child index for a given parent - uint8_t FindChildIndex(UsbDeviceAddress addr, uint8_t start = 1) { - for(uint8_t i = (start < 1 || start >= MAX_DEVICES_ALLOWED) ? 1 : start; i < MAX_DEVICES_ALLOWED; i++) { - if(thePool[i].address.bmParent == addr.bmAddress) - return i; - } - return 0; - }; + uint8_t FindChildIndex(UsbDeviceAddress addr, uint8_t start = 1) { + for (uint8_t i = (start < 1 || start >= MAX_DEVICES_ALLOWED) ? 1 : start; i < MAX_DEVICES_ALLOWED; i++) { + if (thePool[i].address.bmParent == addr.bmAddress) + return i; + } + return 0; + } - // Frees address entry specified by index parameter + // Frees address entry specified by index parameter - void FreeAddressByIndex(uint8_t index) { - // Zero field is reserved and should not be affected - if(index == 0) - return; + void FreeAddressByIndex(uint8_t index) { + // Zero field is reserved and should not be affected + if (index == 0) return; - UsbDeviceAddress uda = thePool[index].address; - // If a hub was switched off all port addresses should be freed - if(uda.bmHub == 1) { - for(uint8_t i = 1; (i = FindChildIndex(uda, i));) - FreeAddressByIndex(i); + UsbDeviceAddress uda = thePool[index].address; + // If a hub was switched off all port addresses should be freed + if (uda.bmHub == 1) { + for (uint8_t i = 1; (i = FindChildIndex(uda, i));) + FreeAddressByIndex(i); - // If the hub had the last allocated address, hubCounter should be decremented - if(hubCounter == uda.bmAddress) - hubCounter--; - } - InitEntry(index); - } + // If the hub had the last allocated address, hubCounter should be decremented + if (hubCounter == uda.bmAddress) hubCounter--; + } + InitEntry(index); + } - // Initializes the whole address pool at once + // Initialize the whole address pool at once - void InitAllAddresses() { - for(uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++) - InitEntry(i); + void InitAllAddresses() { + for (uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++) + InitEntry(i); - hubCounter = 0; - }; + hubCounter = 0; + } public: - AddressPoolImpl() : hubCounter(0) { - // Zero address is reserved - InitEntry(0); - - thePool[0].address.devAddress = 0; - thePool[0].epinfo = &dev0ep; - dev0ep.epAddr = 0; - dev0ep.maxPktSize = 8; - dev0ep.bmSndToggle = 0; // Set DATA0/1 toggles to 0 - dev0ep.bmRcvToggle = 0; - dev0ep.bmNakPower = USB_NAK_MAX_POWER; - - InitAllAddresses(); - }; - - // Returns a pointer to a specified address entry - - virtual UsbDevice* GetUsbDevicePtr(uint8_t addr) { - if(!addr) - return thePool; - - uint8_t index = FindAddressIndex(addr); - - return (!index) ? NULL : thePool + index; - }; - - // Performs an operation specified by pfunc for each addressed device - - void ForEachUsbDevice(UsbDeviceHandleFunc pfunc) { - if(!pfunc) - return; - - for(uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++) - if(thePool[i].address.devAddress) - pfunc(thePool + i); - }; - - // Allocates new address - - virtual uint8_t AllocAddress(uint8_t parent, bool is_hub = false, uint8_t port = 0) { - /* if (parent != 0 && port == 0) - USB_HOST_SERIAL.println("PRT:0"); */ - UsbDeviceAddress _parent; - _parent.devAddress = parent; - if(_parent.bmReserved || port > 7) - //if(parent > 127 || port > 7) - return 0; - - if(is_hub && hubCounter == 7) - return 0; - - // finds first empty address entry starting from one - uint8_t index = FindAddressIndex(0); - - if(!index) // if empty entry is not found - return 0; - - if(_parent.devAddress == 0) { - if(is_hub) { - thePool[index].address.devAddress = 0x41; - hubCounter++; - } else - thePool[index].address.devAddress = 1; - - return thePool[index].address.devAddress; - } - - UsbDeviceAddress addr; - addr.devAddress = 0; // Ensure all bits are zero - addr.bmParent = _parent.bmAddress; - if(is_hub) { - addr.bmHub = 1; - addr.bmAddress = ++hubCounter; - } else { - addr.bmHub = 0; - addr.bmAddress = port; - } - thePool[index].address = addr; - /* - USB_HOST_SERIAL.print("Addr:"); - USB_HOST_SERIAL.print(addr.bmHub, HEX); - USB_HOST_SERIAL.print("."); - USB_HOST_SERIAL.print(addr.bmParent, HEX); - USB_HOST_SERIAL.print("."); - USB_HOST_SERIAL.println(addr.bmAddress, HEX); - */ - return thePool[index].address.devAddress; - }; - - // Empties pool entry - - virtual void FreeAddress(uint8_t addr) { - // if the root hub is disconnected all the addresses should be initialized - if(addr == 0x41) { - InitAllAddresses(); - return; - } - uint8_t index = FindAddressIndex(addr); - FreeAddressByIndex(index); - }; - - // Returns number of hubs attached - // It can be rather helpfull to find out if there are hubs attached than getting the exact number of hubs. - //uint8_t GetNumHubs() - //{ - // return hubCounter; - //}; - //uint8_t GetNumDevices() - //{ - // uint8_t counter = 0; - - // for (uint8_t i=1; i 7) + //if(parent > 127 || port > 7) + return 0; + + if (is_hub && hubCounter == 7) return 0; + + // finds first empty address entry starting from one + uint8_t index = FindAddressIndex(0); + + if (!index) return 0; // if empty entry is not found + + if (_parent.devAddress == 0) { + if (is_hub) { + thePool[index].address.devAddress = 0x41; + hubCounter++; + } + else + thePool[index].address.devAddress = 1; + + return thePool[index].address.devAddress; + } + + UsbDeviceAddress addr; + addr.devAddress = 0; // Ensure all bits are zero + addr.bmParent = _parent.bmAddress; + if (is_hub) { + addr.bmHub = 1; + addr.bmAddress = ++hubCounter; + } + else { + addr.bmHub = 0; + addr.bmAddress = port; + } + thePool[index].address = addr; + /* + USB_HOST_SERIAL.print("Addr:"); + USB_HOST_SERIAL.print(addr.bmHub, HEX); + USB_HOST_SERIAL.print("."); + USB_HOST_SERIAL.print(addr.bmParent, HEX); + USB_HOST_SERIAL.print("."); + USB_HOST_SERIAL.println(addr.bmAddress, HEX); + */ + return thePool[index].address.devAddress; + } + + // Empty the pool entry + + virtual void FreeAddress(uint8_t addr) { + // if the root hub is disconnected all the addresses should be initialized + if (addr == 0x41) { + InitAllAddresses(); + return; + } + FreeAddressByIndex(FindAddressIndex(addr)); + } + + // Return number of hubs attached + // It can be helpful to find out if hubs are attached when getting the exact number of hubs. + //uint8_t GetNumHubs() { return hubCounter; } + //uint8_t GetNumDevices() { + // uint8_t counter = 0; + // for (uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++) + // if (thePool[i].address != 0); counter++; + // return counter; + //} }; - -#endif // __ADDRESS_H__ diff --git a/Marlin/src/sd/usb_flashdrive/lib/confdescparser.h b/Marlin/src/sd/usb_flashdrive/lib/confdescparser.h index 6a38e9073..69f2a9645 100644 --- a/Marlin/src/sd/usb_flashdrive/lib/confdescparser.h +++ b/Marlin/src/sd/usb_flashdrive/lib/confdescparser.h @@ -22,197 +22,180 @@ * Web : http://www.circuitsathome.com * e-mail : support@circuitsathome.com */ -#if !defined(_usb_h_) || defined(__CONFDESCPARSER_H__) -#error "Never include confdescparser.h directly; include Usb.h instead" -#else +#pragma once -#define __CONFDESCPARSER_H__ +#ifndef _usb_h_ + #error "Never include confdescparser.h directly; include Usb.h instead" +#endif class UsbConfigXtracter { public: - //virtual void ConfigXtract(const USB_CONFIGURATION_DESCRIPTOR *conf) = 0; - //virtual void InterfaceXtract(uint8_t conf, const USB_INTERFACE_DESCRIPTOR *iface) = 0; + //virtual void ConfigXtract(const USB_CONFIGURATION_DESCRIPTOR *conf) = 0; + //virtual void InterfaceXtract(uint8_t conf, const USB_INTERFACE_DESCRIPTOR *iface) = 0; - virtual void EndpointXtract(uint8_t conf __attribute__((unused)), uint8_t iface __attribute__((unused)), uint8_t alt __attribute__((unused)), uint8_t proto __attribute__((unused)), const USB_ENDPOINT_DESCRIPTOR *ep __attribute__((unused))) { - }; + virtual void EndpointXtract(uint8_t conf __attribute__((unused)), uint8_t iface __attribute__((unused)), uint8_t alt __attribute__((unused)), uint8_t proto __attribute__((unused)), const USB_ENDPOINT_DESCRIPTOR *ep __attribute__((unused))) { + } }; -#define CP_MASK_COMPARE_CLASS 1 -#define CP_MASK_COMPARE_SUBCLASS 2 -#define CP_MASK_COMPARE_PROTOCOL 4 -#define CP_MASK_COMPARE_ALL 7 +#define CP_MASK_COMPARE_CLASS 1 +#define CP_MASK_COMPARE_SUBCLASS 2 +#define CP_MASK_COMPARE_PROTOCOL 4 +#define CP_MASK_COMPARE_ALL 7 // Configuration Descriptor Parser Class Template template class ConfigDescParser : public USBReadParser { - UsbConfigXtracter *theXtractor; - MultiValueBuffer theBuffer; - MultiByteValueParser valParser; - ByteSkipper theSkipper; - uint8_t varBuffer[16 /*sizeof(USB_CONFIGURATION_DESCRIPTOR)*/]; + UsbConfigXtracter *theXtractor; + MultiValueBuffer theBuffer; + MultiByteValueParser valParser; + ByteSkipper theSkipper; + uint8_t varBuffer[16 /*sizeof(USB_CONFIGURATION_DESCRIPTOR)*/]; - uint8_t stateParseDescr; // ParseDescriptor state + uint8_t stateParseDescr; // ParseDescriptor state - uint8_t dscrLen; // Descriptor length - uint8_t dscrType; // Descriptor type + uint8_t dscrLen; // Descriptor length + uint8_t dscrType; // Descriptor type - bool isGoodInterface; // Apropriate interface flag - uint8_t confValue; // Configuration value - uint8_t protoValue; // Protocol value - uint8_t ifaceNumber; // Interface number - uint8_t ifaceAltSet; // Interface alternate settings + bool isGoodInterface; // Apropriate interface flag + uint8_t confValue; // Configuration value + uint8_t protoValue; // Protocol value + uint8_t ifaceNumber; // Interface number + uint8_t ifaceAltSet; // Interface alternate settings - bool UseOr; - bool ParseDescriptor(uint8_t **pp, uint16_t *pcntdn); - void PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc); + bool UseOr; + bool ParseDescriptor(uint8_t **pp, uint16_t *pcntdn); + void PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc); public: - void SetOR(void) { - UseOr = true; - } - ConfigDescParser(UsbConfigXtracter *xtractor); - void Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset); + void SetOR(void) { UseOr = true; } + ConfigDescParser(UsbConfigXtracter *xtractor); + void Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset); }; template ConfigDescParser::ConfigDescParser(UsbConfigXtracter *xtractor) : -theXtractor(xtractor), -stateParseDescr(0), -dscrLen(0), -dscrType(0), -UseOr(false) { - theBuffer.pValue = varBuffer; - valParser.Initialize(&theBuffer); - theSkipper.Initialize(&theBuffer); -}; + theXtractor(xtractor), + stateParseDescr(0), + dscrLen(0), + dscrType(0), + UseOr(false) { + theBuffer.pValue = varBuffer; + valParser.Initialize(&theBuffer); + theSkipper.Initialize(&theBuffer); + }; template void ConfigDescParser::Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset __attribute__((unused))) { - uint16_t cntdn = (uint16_t)len; - uint8_t *p = (uint8_t*)pbuf; - - while(cntdn) - if(!ParseDescriptor(&p, &cntdn)) - return; + uint16_t cntdn = (uint16_t)len; + uint8_t *p = (uint8_t*)pbuf; + while (cntdn) if (!ParseDescriptor(&p, &cntdn)) return; } /* Parser for the configuration descriptor. Takes values for class, subclass, protocol fields in interface descriptor and compare masks for them. When the match is found, calls EndpointXtract passing buffer containing endpoint descriptor */ template bool ConfigDescParser::ParseDescriptor(uint8_t **pp, uint16_t *pcntdn) { - USB_CONFIGURATION_DESCRIPTOR* ucd = reinterpret_cast(varBuffer); - USB_INTERFACE_DESCRIPTOR* uid = reinterpret_cast(varBuffer); - switch(stateParseDescr) { - case 0: - theBuffer.valueSize = 2; - valParser.Initialize(&theBuffer); - stateParseDescr = 1; - case 1: - if(!valParser.Parse(pp, pcntdn)) - return false; - dscrLen = *((uint8_t*)theBuffer.pValue); - dscrType = *((uint8_t*)theBuffer.pValue + 1); - stateParseDescr = 2; - case 2: - // This is a sort of hack. Assuming that two bytes are all ready in the buffer - // the pointer is positioned two bytes ahead in order for the rest of descriptor - // to be read right after the size and the type fields. - // This should be used carefully. varBuffer should be used directly to handle data - // in the buffer. - theBuffer.pValue = varBuffer + 2; - stateParseDescr = 3; - case 3: - switch(dscrType) { - case USB_DESCRIPTOR_INTERFACE: - isGoodInterface = false; - break; - case USB_DESCRIPTOR_CONFIGURATION: - case USB_DESCRIPTOR_ENDPOINT: - case HID_DESCRIPTOR_HID: - break; - } - theBuffer.valueSize = dscrLen - 2; - valParser.Initialize(&theBuffer); - stateParseDescr = 4; - case 4: - switch(dscrType) { - case USB_DESCRIPTOR_CONFIGURATION: - if(!valParser.Parse(pp, pcntdn)) - return false; - confValue = ucd->bConfigurationValue; - break; - case USB_DESCRIPTOR_INTERFACE: - if(!valParser.Parse(pp, pcntdn)) - return false; - if((MASK & CP_MASK_COMPARE_CLASS) && uid->bInterfaceClass != CLASS_ID) - break; - if((MASK & CP_MASK_COMPARE_SUBCLASS) && uid->bInterfaceSubClass != SUBCLASS_ID) - break; - if(UseOr) { - if((!((MASK & CP_MASK_COMPARE_PROTOCOL) && uid->bInterfaceProtocol))) - break; - } else { - if((MASK & CP_MASK_COMPARE_PROTOCOL) && uid->bInterfaceProtocol != PROTOCOL_ID) - break; - } - isGoodInterface = true; - ifaceNumber = uid->bInterfaceNumber; - ifaceAltSet = uid->bAlternateSetting; - protoValue = uid->bInterfaceProtocol; - break; - case USB_DESCRIPTOR_ENDPOINT: - if(!valParser.Parse(pp, pcntdn)) - return false; - if(isGoodInterface) - if(theXtractor) - theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*)varBuffer); - break; - //case HID_DESCRIPTOR_HID: - // if (!valParser.Parse(pp, pcntdn)) - // return false; - // PrintHidDescriptor((const USB_HID_DESCRIPTOR*)varBuffer); - // break; - default: - if(!theSkipper.Skip(pp, pcntdn, dscrLen - 2)) - return false; - } - theBuffer.pValue = varBuffer; - stateParseDescr = 0; - } - return true; + USB_CONFIGURATION_DESCRIPTOR* ucd = reinterpret_cast(varBuffer); + USB_INTERFACE_DESCRIPTOR* uid = reinterpret_cast(varBuffer); + switch (stateParseDescr) { + case 0: + theBuffer.valueSize = 2; + valParser.Initialize(&theBuffer); + stateParseDescr = 1; + case 1: + if (!valParser.Parse(pp, pcntdn)) return false; + dscrLen = *((uint8_t*)theBuffer.pValue); + dscrType = *((uint8_t*)theBuffer.pValue + 1); + stateParseDescr = 2; + case 2: + // This is a sort of hack. Assuming that two bytes are all ready in the buffer + // the pointer is positioned two bytes ahead in order for the rest of descriptor + // to be read right after the size and the type fields. + // This should be used carefully. varBuffer should be used directly to handle data + // in the buffer. + theBuffer.pValue = varBuffer + 2; + stateParseDescr = 3; + case 3: + switch (dscrType) { + case USB_DESCRIPTOR_INTERFACE: + isGoodInterface = false; + break; + case USB_DESCRIPTOR_CONFIGURATION: + case USB_DESCRIPTOR_ENDPOINT: + case HID_DESCRIPTOR_HID: + break; + } + theBuffer.valueSize = dscrLen - 2; + valParser.Initialize(&theBuffer); + stateParseDescr = 4; + case 4: + switch (dscrType) { + case USB_DESCRIPTOR_CONFIGURATION: + if (!valParser.Parse(pp, pcntdn)) return false; + confValue = ucd->bConfigurationValue; + break; + case USB_DESCRIPTOR_INTERFACE: + if (!valParser.Parse(pp, pcntdn)) return false; + if ((MASK & CP_MASK_COMPARE_CLASS) && uid->bInterfaceClass != CLASS_ID) + break; + if ((MASK & CP_MASK_COMPARE_SUBCLASS) && uid->bInterfaceSubClass != SUBCLASS_ID) + break; + if (UseOr) { + if ((!((MASK & CP_MASK_COMPARE_PROTOCOL) && uid->bInterfaceProtocol))) break; + } + else if ((MASK & CP_MASK_COMPARE_PROTOCOL) && uid->bInterfaceProtocol != PROTOCOL_ID) + break; + isGoodInterface = true; + ifaceNumber = uid->bInterfaceNumber; + ifaceAltSet = uid->bAlternateSetting; + protoValue = uid->bInterfaceProtocol; + break; + case USB_DESCRIPTOR_ENDPOINT: + if (!valParser.Parse(pp, pcntdn)) return false; + if (isGoodInterface && theXtractor) + theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*)varBuffer); + break; + //case HID_DESCRIPTOR_HID: + // if (!valParser.Parse(pp, pcntdn)) return false; + // PrintHidDescriptor((const USB_HID_DESCRIPTOR*)varBuffer); + // break; + default: + if (!theSkipper.Skip(pp, pcntdn, dscrLen - 2)) return false; + } + theBuffer.pValue = varBuffer; + stateParseDescr = 0; + } + return true; } template void ConfigDescParser::PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc) { - Notify(PSTR("\r\n\r\nHID Descriptor:\r\n"), 0x80); - Notify(PSTR("bDescLength:\t\t"), 0x80); - PrintHex (pDesc->bLength, 0x80); + Notify(PSTR("\r\n\r\nHID Descriptor:\r\n"), 0x80); + Notify(PSTR("bDescLength:\t\t"), 0x80); + PrintHex (pDesc->bLength, 0x80); - Notify(PSTR("\r\nbDescriptorType:\t"), 0x80); - PrintHex (pDesc->bDescriptorType, 0x80); + Notify(PSTR("\r\nbDescriptorType:\t"), 0x80); + PrintHex (pDesc->bDescriptorType, 0x80); - Notify(PSTR("\r\nbcdHID:\t\t\t"), 0x80); - PrintHex (pDesc->bcdHID, 0x80); + Notify(PSTR("\r\nbcdHID:\t\t\t"), 0x80); + PrintHex (pDesc->bcdHID, 0x80); - Notify(PSTR("\r\nbCountryCode:\t\t"), 0x80); - PrintHex (pDesc->bCountryCode, 0x80); + Notify(PSTR("\r\nbCountryCode:\t\t"), 0x80); + PrintHex (pDesc->bCountryCode, 0x80); - Notify(PSTR("\r\nbNumDescriptors:\t"), 0x80); - PrintHex (pDesc->bNumDescriptors, 0x80); + Notify(PSTR("\r\nbNumDescriptors:\t"), 0x80); + PrintHex (pDesc->bNumDescriptors, 0x80); - for(uint8_t i = 0; i < pDesc->bNumDescriptors; i++) { - HID_CLASS_DESCRIPTOR_LEN_AND_TYPE *pLT = (HID_CLASS_DESCRIPTOR_LEN_AND_TYPE*)&(pDesc->bDescrType); + for (uint8_t i = 0; i < pDesc->bNumDescriptors; i++) { + HID_CLASS_DESCRIPTOR_LEN_AND_TYPE *pLT = (HID_CLASS_DESCRIPTOR_LEN_AND_TYPE*)&(pDesc->bDescrType); - Notify(PSTR("\r\nbDescrType:\t\t"), 0x80); - PrintHex (pLT[i].bDescrType, 0x80); + Notify(PSTR("\r\nbDescrType:\t\t"), 0x80); + PrintHex (pLT[i].bDescrType, 0x80); - Notify(PSTR("\r\nwDescriptorLength:\t"), 0x80); - PrintHex (pLT[i].wDescriptorLength, 0x80); - } - Notify(PSTR("\r\n"), 0x80); + Notify(PSTR("\r\nwDescriptorLength:\t"), 0x80); + PrintHex (pLT[i].wDescriptorLength, 0x80); + } + Notify(PSTR("\r\n"), 0x80); } - - -#endif // __CONFDESCPARSER_H__ diff --git a/Marlin/src/sd/usb_flashdrive/lib/hexdump.h b/Marlin/src/sd/usb_flashdrive/lib/hexdump.h index 7591efdc3..59c3b48f6 100644 --- a/Marlin/src/sd/usb_flashdrive/lib/hexdump.h +++ b/Marlin/src/sd/usb_flashdrive/lib/hexdump.h @@ -22,49 +22,47 @@ * Web : http://www.circuitsathome.com * e-mail : support@circuitsathome.com */ +#pragma once -#if !defined(_usb_h_) || defined(__HEXDUMP_H__) -#error "Never include hexdump.h directly; include Usb.h instead" -#else -#define __HEXDUMP_H__ +#ifndef _usb_h_ + #error "Never include hexdump.h directly; include Usb.h instead" +#endif extern int UsbDEBUGlvl; template class HexDumper : public BASE_CLASS { - uint8_t byteCount; - OFFSET_TYPE byteTotal; + uint8_t byteCount; + OFFSET_TYPE byteTotal; public: - HexDumper() : byteCount(0), byteTotal(0) { - }; + HexDumper() : byteCount(0), byteTotal(0) { + }; - void Initialize() { - byteCount = 0; - byteTotal = 0; - }; + void Initialize() { + byteCount = 0; + byteTotal = 0; + }; - void Parse(const LEN_TYPE len, const uint8_t *pbuf, const OFFSET_TYPE &offset); + void Parse(const LEN_TYPE len, const uint8_t *pbuf, const OFFSET_TYPE &offset); }; template void HexDumper::Parse(const LEN_TYPE len, const uint8_t *pbuf, const OFFSET_TYPE &offset __attribute__((unused))) { - if(UsbDEBUGlvl >= 0x80) { // Fully bypass this block of code if we do not debug. - for(LEN_TYPE j = 0; j < len; j++, byteCount++, byteTotal++) { - if(!byteCount) { - PrintHex (byteTotal, 0x80); - E_Notify(PSTR(": "), 0x80); - } - PrintHex (pbuf[j], 0x80); - E_Notify(PSTR(" "), 0x80); + if (UsbDEBUGlvl >= 0x80) { // Fully bypass this block of code if we do not debug. + for (LEN_TYPE j = 0; j < len; j++, byteCount++, byteTotal++) { + if (!byteCount) { + PrintHex (byteTotal, 0x80); + E_Notify(PSTR(": "), 0x80); + } + PrintHex (pbuf[j], 0x80); + E_Notify(PSTR(" "), 0x80); - if(byteCount == 15) { - E_Notify(PSTR("\r\n"), 0x80); - byteCount = 0xFF; - } - } - } + if (byteCount == 15) { + E_Notify(PSTR("\r\n"), 0x80); + byteCount = 0xFF; + } + } + } } - -#endif // __HEXDUMP_H__ diff --git a/Marlin/src/sd/usb_flashdrive/lib/macros.h b/Marlin/src/sd/usb_flashdrive/lib/macros.h index 327ccb229..0fb5c02ff 100644 --- a/Marlin/src/sd/usb_flashdrive/lib/macros.h +++ b/Marlin/src/sd/usb_flashdrive/lib/macros.h @@ -22,13 +22,12 @@ * Web : http://www.circuitsathome.com * e-mail : support@circuitsathome.com */ +#pragma once #ifndef _usb_h_ #error "Never include macros.h directly; include Usb.h instead" #endif -#pragma once - //////////////////////////////////////////////////////////////////////////////// // HANDY MACROS //////////////////////////////////////////////////////////////////////////////// @@ -36,7 +35,7 @@ #define VALUE_BETWEEN(v,l,h) (((v)>(l)) && ((v)<(h))) #define VALUE_WITHIN(v,l,h) (((v)>=(l)) && ((v)<=(h))) #define output_pgm_message(wa,fp,mp,el) wa = &mp, fp((char *)pgm_read_pointer(wa), el) -#define output_if_between(v,l,h,wa,fp,mp,el) if(VALUE_BETWEEN(v,l,h)) output_pgm_message(wa,fp,mp[v-(l+1)],el); +#define output_if_between(v,l,h,wa,fp,mp,el) if (VALUE_BETWEEN(v,l,h)) output_pgm_message(wa,fp,mp[v-(l+1)],el); #define SWAP(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b))) #ifndef __BYTE_GRABBING_DEFINED__ diff --git a/Marlin/src/sd/usb_flashdrive/lib/masstorage.cpp b/Marlin/src/sd/usb_flashdrive/lib/masstorage.cpp index 1ed43709f..eac4bebe5 100644 --- a/Marlin/src/sd/usb_flashdrive/lib/masstorage.cpp +++ b/Marlin/src/sd/usb_flashdrive/lib/masstorage.cpp @@ -44,9 +44,7 @@ const uint8_t BulkOnly::epInterruptInIndex = 3; * @return media capacity */ uint32_t BulkOnly::GetCapacity(uint8_t lun) { - if(LUNOk[lun]) - return CurrentCapacity[lun]; - return 0LU; + return LUNOk[lun] ? CurrentCapacity[lun] : 0UL; } /** @@ -56,9 +54,7 @@ uint32_t BulkOnly::GetCapacity(uint8_t lun) { * @return media sector size */ uint16_t BulkOnly::GetSectorSize(uint8_t lun) { - if(LUNOk[lun]) - return CurrentSectorSize[lun]; - return 0U; + return LUNOk[lun] ? CurrentSectorSize[lun] : 0U; } /** @@ -67,9 +63,7 @@ uint16_t BulkOnly::GetSectorSize(uint8_t lun) { * @param lun Logical Unit Number * @return true if LUN is ready for use */ -bool BulkOnly::LUNIsGood(uint8_t lun) { - return LUNOk[lun]; -} +bool BulkOnly::LUNIsGood(uint8_t lun) { return LUNOk[lun]; } /** * Test if LUN is write protected @@ -77,9 +71,7 @@ bool BulkOnly::LUNIsGood(uint8_t lun) { * @param lun Logical Unit Number * @return cached status of write protect switch */ -bool BulkOnly::WriteProtected(uint8_t lun) { - return WriteOk[lun]; -} +bool BulkOnly::WriteProtected(uint8_t lun) { return WriteOk[lun]; } /** * Wrap and execute a SCSI CDB with length of 6 @@ -91,10 +83,10 @@ bool BulkOnly::WriteProtected(uint8_t lun) { * @return */ uint8_t BulkOnly::SCSITransaction6(CDB6_t *cdb, uint16_t buf_size, void *buf, uint8_t dir) { - // promote buf_size to 32bits. - CommandBlockWrapper cbw = CommandBlockWrapper(++dCBWTag, (uint32_t)buf_size, cdb, dir); - //SetCurLUN(cdb->LUN); - return (HandleSCSIError(Transaction(&cbw, buf_size, buf))); + // promote buf_size to 32bits. + CommandBlockWrapper cbw = CommandBlockWrapper(++dCBWTag, (uint32_t)buf_size, cdb, dir); + //SetCurLUN(cdb->LUN); + return (HandleSCSIError(Transaction(&cbw, buf_size, buf))); } /** @@ -107,10 +99,10 @@ uint8_t BulkOnly::SCSITransaction6(CDB6_t *cdb, uint16_t buf_size, void *buf, ui * @return */ uint8_t BulkOnly::SCSITransaction10(CDB10_t *cdb, uint16_t buf_size, void *buf, uint8_t dir) { - // promote buf_size to 32bits. - CommandBlockWrapper cbw = CommandBlockWrapper(++dCBWTag, (uint32_t)buf_size, cdb, dir); - //SetCurLUN(cdb->LUN); - return (HandleSCSIError(Transaction(&cbw, buf_size, buf))); + // promote buf_size to 32bits. + CommandBlockWrapper cbw = CommandBlockWrapper(++dCBWTag, (uint32_t)buf_size, cdb, dir); + //SetCurLUN(cdb->LUN); + return (HandleSCSIError(Transaction(&cbw, buf_size, buf))); } /** @@ -122,11 +114,11 @@ uint8_t BulkOnly::SCSITransaction10(CDB10_t *cdb, uint16_t buf_size, void *buf, * @return */ uint8_t BulkOnly::LockMedia(uint8_t lun, uint8_t lock) { - Notify(PSTR("\r\nLockMedia\r\n"), 0x80); - Notify(PSTR("---------\r\n"), 0x80); + Notify(PSTR("\r\nLockMedia\r\n"), 0x80); + Notify(PSTR("---------\r\n"), 0x80); - CDB6_t cdb = CDB6_t(SCSI_CMD_PREVENT_REMOVAL, lun, (uint8_t)0, lock); - return SCSITransaction6(&cdb, (uint16_t)0, NULL, (uint8_t)MASS_CMD_DIR_IN); + CDB6_t cdb = CDB6_t(SCSI_CMD_PREVENT_REMOVAL, lun, (uint8_t)0, lock); + return SCSITransaction6(&cdb, (uint16_t)0, NULL, (uint8_t)MASS_CMD_DIR_IN); } /** @@ -138,17 +130,18 @@ uint8_t BulkOnly::LockMedia(uint8_t lun, uint8_t lock) { * @return 0 on success */ uint8_t BulkOnly::MediaCTL(uint8_t lun, uint8_t ctl) { - Notify(PSTR("\r\nMediaCTL\r\n"), 0x80); - Notify(PSTR("-----------------\r\n"), 0x80); - - uint8_t rcode = MASS_ERR_UNIT_NOT_READY; - if(bAddress) { - CDB6_t cdb = CDB6_t(SCSI_CMD_START_STOP_UNIT, lun, ctl & 0x03, 0); - rcode = SCSITransaction6(&cdb, (uint16_t)0, NULL, (uint8_t)MASS_CMD_DIR_OUT); - } else { - SetCurLUN(lun); - } - return rcode; + Notify(PSTR("\r\nMediaCTL\r\n"), 0x80); + Notify(PSTR("-----------------\r\n"), 0x80); + + uint8_t rcode = MASS_ERR_UNIT_NOT_READY; + if (bAddress) { + CDB6_t cdb = CDB6_t(SCSI_CMD_START_STOP_UNIT, lun, ctl & 0x03, 0); + rcode = SCSITransaction6(&cdb, (uint16_t)0, NULL, (uint8_t)MASS_CMD_DIR_OUT); + } + else + SetCurLUN(lun); + + return rcode; } /** @@ -162,27 +155,27 @@ uint8_t BulkOnly::MediaCTL(uint8_t lun, uint8_t ctl) { * @return 0 on success */ uint8_t BulkOnly::Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, uint8_t *buf) { - if(!LUNOk[lun]) return MASS_ERR_NO_MEDIA; - Notify(PSTR("\r\nRead LUN:\t"), 0x80); - D_PrintHex (lun, 0x90); - Notify(PSTR("\r\nLBA:\t\t"), 0x90); - D_PrintHex (addr, 0x90); - Notify(PSTR("\r\nblocks:\t\t"), 0x90); - D_PrintHex (blocks, 0x90); - Notify(PSTR("\r\nblock size:\t"), 0x90); - D_PrintHex (bsize, 0x90); - Notify(PSTR("\r\n---------\r\n"), 0x80); - CDB10_t cdb = CDB10_t(SCSI_CMD_READ_10, lun, blocks, addr); + if (!LUNOk[lun]) return MASS_ERR_NO_MEDIA; + Notify(PSTR("\r\nRead LUN:\t"), 0x80); + D_PrintHex (lun, 0x90); + Notify(PSTR("\r\nLBA:\t\t"), 0x90); + D_PrintHex (addr, 0x90); + Notify(PSTR("\r\nblocks:\t\t"), 0x90); + D_PrintHex (blocks, 0x90); + Notify(PSTR("\r\nblock size:\t"), 0x90); + D_PrintHex (bsize, 0x90); + Notify(PSTR("\r\n---------\r\n"), 0x80); + CDB10_t cdb = CDB10_t(SCSI_CMD_READ_10, lun, blocks, addr); again: - uint8_t er = SCSITransaction10(&cdb, ((uint16_t)bsize * blocks), buf, (uint8_t)MASS_CMD_DIR_IN); - - if(er == MASS_ERR_STALL) { - MediaCTL(lun, 1); - delay(150); - if(!TestUnitReady(lun)) goto again; - } - return er; + uint8_t er = SCSITransaction10(&cdb, ((uint16_t)bsize * blocks), buf, (uint8_t)MASS_CMD_DIR_IN); + + if (er == MASS_ERR_STALL) { + MediaCTL(lun, 1); + delay(150); + if (!TestUnitReady(lun)) goto again; + } + return er; } /** @@ -196,28 +189,28 @@ again: * @return 0 on success */ uint8_t BulkOnly::Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, const uint8_t * buf) { - if(!LUNOk[lun]) return MASS_ERR_NO_MEDIA; - if(!WriteOk[lun]) return MASS_ERR_WRITE_PROTECTED; - Notify(PSTR("\r\nWrite LUN:\t"), 0x80); - D_PrintHex (lun, 0x90); - Notify(PSTR("\r\nLBA:\t\t"), 0x90); - D_PrintHex (addr, 0x90); - Notify(PSTR("\r\nblocks:\t\t"), 0x90); - D_PrintHex (blocks, 0x90); - Notify(PSTR("\r\nblock size:\t"), 0x90); - D_PrintHex (bsize, 0x90); - Notify(PSTR("\r\n---------\r\n"), 0x80); - CDB10_t cdb = CDB10_t(SCSI_CMD_WRITE_10, lun, blocks, addr); + if (!LUNOk[lun]) return MASS_ERR_NO_MEDIA; + if (!WriteOk[lun]) return MASS_ERR_WRITE_PROTECTED; + Notify(PSTR("\r\nWrite LUN:\t"), 0x80); + D_PrintHex (lun, 0x90); + Notify(PSTR("\r\nLBA:\t\t"), 0x90); + D_PrintHex (addr, 0x90); + Notify(PSTR("\r\nblocks:\t\t"), 0x90); + D_PrintHex (blocks, 0x90); + Notify(PSTR("\r\nblock size:\t"), 0x90); + D_PrintHex (bsize, 0x90); + Notify(PSTR("\r\n---------\r\n"), 0x80); + CDB10_t cdb = CDB10_t(SCSI_CMD_WRITE_10, lun, blocks, addr); again: - uint8_t er = SCSITransaction10(&cdb, ((uint16_t)bsize * blocks), (void*)buf, (uint8_t)MASS_CMD_DIR_OUT); - - if(er == MASS_ERR_WRITE_STALL) { - MediaCTL(lun, 1); - delay(150); - if(!TestUnitReady(lun)) goto again; - } - return er; + uint8_t er = SCSITransaction10(&cdb, ((uint16_t)bsize * blocks), (void*)buf, (uint8_t)MASS_CMD_DIR_OUT); + + if (er == MASS_ERR_WRITE_STALL) { + MediaCTL(lun, 1); + delay(150); + if (!TestUnitReady(lun)) goto again; + } + return er; } // End of user functions, the remaining code below is driver internals. @@ -236,10 +229,9 @@ qNextPollTime(0), bPollEnable(false), //dCBWTag(0), bLastUsbError(0) { - ClearAllEP(); - dCBWTag = 0; - if(pUsb) - pUsb->RegisterDeviceClass(this); + ClearAllEP(); + dCBWTag = 0; + if (pUsb) pUsb->RegisterDeviceClass(this); } /** @@ -258,71 +250,66 @@ bLastUsbError(0) { */ uint8_t BulkOnly::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) { - const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR); + const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR); - uint8_t buf[constBufSize]; - USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf); - uint8_t rcode; - UsbDevice *p = NULL; - EpInfo *oldep_ptr = NULL; - USBTRACE("MS ConfigureDevice\r\n"); - ClearAllEP(); - AddressPool &addrPool = pUsb->GetAddressPool(); + uint8_t buf[constBufSize]; + USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf); + uint8_t rcode; + UsbDevice *p = NULL; + EpInfo *oldep_ptr = NULL; + USBTRACE("MS ConfigureDevice\r\n"); + ClearAllEP(); + AddressPool &addrPool = pUsb->GetAddressPool(); + if (bAddress) return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE; - if(bAddress) - return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE; + // + // Get pointer to pseudo device with address 0 assigned + p = addrPool.GetUsbDevicePtr(0); + if (!p) return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; - // - // Get pointer to pseudo device with address 0 assigned - p = addrPool.GetUsbDevicePtr(0); - if(!p) { - return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; - } + if (!p->epinfo) { + USBTRACE("epinfo\r\n"); + return USB_ERROR_EPINFO_IS_NULL; + } - if(!p->epinfo) { - USBTRACE("epinfo\r\n"); - return USB_ERROR_EPINFO_IS_NULL; - } + // Save old pointer to EP_RECORD of address 0 + oldep_ptr = p->epinfo; - // Save old pointer to EP_RECORD of address 0 - oldep_ptr = p->epinfo; + // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence + p->epinfo = epInfo; - // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence - p->epinfo = epInfo; + p->lowspeed = lowspeed; + // Get device descriptor + rcode = pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*)buf); - p->lowspeed = lowspeed; - // Get device descriptor - rcode = pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*)buf); + // Restore p->epinfo + p->epinfo = oldep_ptr; - // Restore p->epinfo - p->epinfo = oldep_ptr; + if (rcode) goto FailGetDevDescr; - if(rcode) { - goto FailGetDevDescr; - } - // Allocate new address according to device class - bAddress = addrPool.AllocAddress(parent, false, port); + // Allocate new address according to device class + bAddress = addrPool.AllocAddress(parent, false, port); - if(!bAddress) - return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; + if (!bAddress) return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; - // Extract Max Packet Size from the device descriptor - epInfo[0].maxPktSize = udd->bMaxPacketSize0; - // Steal and abuse from epInfo structure to save on memory. - epInfo[1].epAddr = udd->bNumConfigurations; - // - return USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET; + // Extract Max Packet Size from the device descriptor + epInfo[0].maxPktSize = udd->bMaxPacketSize0; + // Steal and abuse from epInfo structure to save on memory. + epInfo[1].epAddr = udd->bNumConfigurations; + // + return USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET; FailGetDevDescr: -#ifdef DEBUG_USB_HOST - NotifyFailGetDevDescr(rcode); -#endif - rcode = USB_ERROR_FailGetDevDescr; - Release(); - return rcode; -}; + #ifdef DEBUG_USB_HOST + NotifyFailGetDevDescr(rcode); + #endif + rcode = USB_ERROR_FailGetDevDescr; + + Release(); + return rcode; +} /** * @param parent (not used) @@ -331,211 +318,206 @@ FailGetDevDescr: * @return 0 for success */ uint8_t BulkOnly::Init(uint8_t parent __attribute__((unused)), uint8_t port __attribute__((unused)), bool lowspeed) { - uint8_t rcode; - uint8_t num_of_conf = epInfo[1].epAddr; // number of configurations - epInfo[1].epAddr = 0; - USBTRACE("MS Init\r\n"); - - AddressPool &addrPool = pUsb->GetAddressPool(); - UsbDevice *p = addrPool.GetUsbDevicePtr(bAddress); - - if(!p) - return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; - - // Assign new address to the device - delay(2000); - rcode = pUsb->setAddr(0, 0, bAddress); - - if(rcode) { - p->lowspeed = false; - addrPool.FreeAddress(bAddress); - bAddress = 0; - USBTRACE2("setAddr:", rcode); - return rcode; - } - - USBTRACE2("Addr:", bAddress); - - p->lowspeed = false; - - p = addrPool.GetUsbDevicePtr(bAddress); - - if(!p) - return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; - - p->lowspeed = lowspeed; - - // Assign epInfo to epinfo pointer - rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); - - if(rcode) - goto FailSetDevTblEntry; + uint8_t rcode; + uint8_t num_of_conf = epInfo[1].epAddr; // number of configurations + epInfo[1].epAddr = 0; + USBTRACE("MS Init\r\n"); - USBTRACE2("NC:", num_of_conf); - - for(uint8_t i = 0; i < num_of_conf; i++) { - ConfigDescParser< USB_CLASS_MASS_STORAGE, - MASS_SUBCLASS_SCSI, - MASS_PROTO_BBB, - CP_MASK_COMPARE_CLASS | - CP_MASK_COMPARE_SUBCLASS | - CP_MASK_COMPARE_PROTOCOL > BulkOnlyParser(this); - - rcode = pUsb->getConfDescr(bAddress, 0, i, &BulkOnlyParser); - - if(rcode) - goto FailGetConfDescr; - - if(bNumEP > 1) - break; + AddressPool &addrPool = pUsb->GetAddressPool(); + UsbDevice *p = addrPool.GetUsbDevicePtr(bAddress); + + if (!p) return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; + + // Assign new address to the device + delay(2000); + rcode = pUsb->setAddr(0, 0, bAddress); + + if (rcode) { + p->lowspeed = false; + addrPool.FreeAddress(bAddress); + bAddress = 0; + USBTRACE2("setAddr:", rcode); + return rcode; + } + + USBTRACE2("Addr:", bAddress); + + p->lowspeed = false; + + p = addrPool.GetUsbDevicePtr(bAddress); + + if (!p) return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; + + p->lowspeed = lowspeed; + + // Assign epInfo to epinfo pointer + rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); + + if (rcode) goto FailSetDevTblEntry; + + USBTRACE2("NC:", num_of_conf); + + for (uint8_t i = 0; i < num_of_conf; i++) { + ConfigDescParser< USB_CLASS_MASS_STORAGE, + MASS_SUBCLASS_SCSI, + MASS_PROTO_BBB, + CP_MASK_COMPARE_CLASS | + CP_MASK_COMPARE_SUBCLASS | + CP_MASK_COMPARE_PROTOCOL > BulkOnlyParser(this); + + rcode = pUsb->getConfDescr(bAddress, 0, i, &BulkOnlyParser); + + if (rcode) goto FailGetConfDescr; + + if (bNumEP > 1) break; + } + + if (bNumEP < 3) return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; + + // Assign epInfo to epinfo pointer + pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo); + + USBTRACE2("Conf:", bConfNum); + + // Set Configuration Value + rcode = pUsb->setConf(bAddress, 0, bConfNum); + + if (rcode) goto FailSetConfDescr; + + //Linux does a 1sec delay after this. + delay(1000); + + rcode = GetMaxLUN(&bMaxLUN); + if (rcode) goto FailGetMaxLUN; + + if (bMaxLUN >= MASS_MAX_SUPPORTED_LUN) bMaxLUN = MASS_MAX_SUPPORTED_LUN - 1; + ErrorMessage (PSTR("MaxLUN"), bMaxLUN); + + delay(1000); // Delay a bit for slow firmware. + + for (uint8_t lun = 0; lun <= bMaxLUN; lun++) { + InquiryResponse response; + rcode = Inquiry(lun, sizeof (InquiryResponse), (uint8_t*) & response); + if (rcode) { + ErrorMessage (PSTR("Inquiry"), rcode); + } + else { + #if 0 + printf("LUN %i `", lun); + uint8_t *buf = response.VendorID; + for (int i = 0; i < 28; i++) printf("%c", buf[i]); + printf("'\r\nQualifier %1.1X ", response.PeripheralQualifier); + printf("Device type %2.2X ", response.DeviceType); + printf("RMB %1.1X ", response.Removable); + printf("SSCS %1.1X ", response.SCCS); + uint8_t sv = response.Version; + printf("SCSI version %2.2X\r\nDevice conforms to ", sv); + switch (sv) { + case 0: + printf("No specific"); + break; + case 1: + printf("ANSI X3.131-1986 (ANSI 1)"); + break; + case 2: + printf("ANSI X3.131-1994 (ANSI 2)"); + break; + case 3: + printf("ANSI INCITS 301-1997 (SPC)"); + break; + case 4: + printf("ANSI INCITS 351-2001 (SPC-2)"); + break; + case 5: + printf("ANSI INCITS 408-2005 (SPC-4)"); + break; + case 6: + printf("T10/1731-D (SPC-4)"); + break; + default: printf("unknown"); } - - if(bNumEP < 3) - return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; - - // Assign epInfo to epinfo pointer - pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo); - - USBTRACE2("Conf:", bConfNum); - - // Set Configuration Value - rcode = pUsb->setConf(bAddress, 0, bConfNum); - - if(rcode) - goto FailSetConfDescr; - - //Linux does a 1sec delay after this. + printf(" standards.\r\n"); + #endif + + uint8_t tries = 0xf0; + while ((rcode = TestUnitReady(lun))) { + if (rcode == 0x08) break; // break on no media, this is OK to do. + // try to lock media and spin up + if (tries < 14) { + LockMedia(lun, 1); + MediaCTL(lun, 1); // I actually have a USB stick that needs this! + } else + delay(2 * (tries + 1)); + tries++; + if (!tries) break; + } + if (!rcode) { delay(1000); + LUNOk[lun] = CheckLUN(lun); + if (!LUNOk[lun]) LUNOk[lun] = CheckLUN(lun); + } + } + } - rcode = GetMaxLUN(&bMaxLUN); - if(rcode) - goto FailGetMaxLUN; - - if(bMaxLUN >= MASS_MAX_SUPPORTED_LUN) bMaxLUN = MASS_MAX_SUPPORTED_LUN - 1; - ErrorMessage (PSTR("MaxLUN"), bMaxLUN); - - delay(1000); // Delay a bit for slow firmware. - - for(uint8_t lun = 0; lun <= bMaxLUN; lun++) { - InquiryResponse response; - rcode = Inquiry(lun, sizeof (InquiryResponse), (uint8_t*) & response); - if(rcode) { - ErrorMessage (PSTR("Inquiry"), rcode); - } else { -#if 0 - printf("LUN %i `", lun); - uint8_t *buf = response.VendorID; - for(int i = 0; i < 28; i++) printf("%c", buf[i]); - printf("'\r\nQualifier %1.1X ", response.PeripheralQualifier); - printf("Device type %2.2X ", response.DeviceType); - printf("RMB %1.1X ", response.Removable); - printf("SSCS %1.1X ", response.SCCS); - uint8_t sv = response.Version; - printf("SCSI version %2.2X\r\nDevice conforms to ", sv); - switch(sv) { - case 0: - printf("No specific"); - break; - case 1: - printf("ANSI X3.131-1986 (ANSI 1)"); - break; - case 2: - printf("ANSI X3.131-1994 (ANSI 2)"); - break; - case 3: - printf("ANSI INCITS 301-1997 (SPC)"); - break; - case 4: - printf("ANSI INCITS 351-2001 (SPC-2)"); - break; - case 5: - printf("ANSI INCITS 408-2005 (SPC-4)"); - break; - case 6: - printf("T10/1731-D (SPC-4)"); - break; - default: - printf("unknown"); - } - printf(" standards.\r\n"); -#endif - uint8_t tries = 0xf0; - while((rcode = TestUnitReady(lun))) { - if(rcode == 0x08) break; // break on no media, this is OK to do. - // try to lock media and spin up - if(tries < 14) { - LockMedia(lun, 1); - MediaCTL(lun, 1); // I actually have a USB stick that needs this! - } else delay(2 * (tries + 1)); - tries++; - if(!tries) break; - } - if(!rcode) { - delay(1000); - LUNOk[lun] = CheckLUN(lun); - if(!LUNOk[lun]) LUNOk[lun] = CheckLUN(lun); - } - } - } + CheckMedia(); + rcode = OnInit(); - CheckMedia(); + if (rcode) goto FailOnInit; - rcode = OnInit(); + #ifdef DEBUG_USB_HOST + USBTRACE("MS configured\r\n\r\n"); + #endif - if(rcode) - goto FailOnInit; + bPollEnable = true; -#ifdef DEBUG_USB_HOST - USBTRACE("MS configured\r\n\r\n"); -#endif + //USBTRACE("Poll enabled\r\n"); + return 0; - bPollEnable = true; + FailSetConfDescr: - //USBTRACE("Poll enabled\r\n"); - return 0; + #ifdef DEBUG_USB_HOST + NotifyFailSetConfDescr(); + goto Fail; + #endif -FailSetConfDescr: -#ifdef DEBUG_USB_HOST - NotifyFailSetConfDescr(); - goto Fail; -#endif + FailOnInit: -FailOnInit: -#ifdef DEBUG_USB_HOST - USBTRACE("OnInit:"); - goto Fail; -#endif + #ifdef DEBUG_USB_HOST + USBTRACE("OnInit:"); + goto Fail; + #endif -FailGetMaxLUN: -#ifdef DEBUG_USB_HOST - USBTRACE("GetMaxLUN:"); - goto Fail; -#endif + FailGetMaxLUN: - //#ifdef DEBUG_USB_HOST - //FailInvalidSectorSize: - // USBTRACE("Sector Size is NOT VALID: "); - // goto Fail; - //#endif + #ifdef DEBUG_USB_HOST + USBTRACE("GetMaxLUN:"); + goto Fail; + #endif -FailSetDevTblEntry: -#ifdef DEBUG_USB_HOST - NotifyFailSetDevTblEntry(); - goto Fail; -#endif + //#ifdef DEBUG_USB_HOST + // FailInvalidSectorSize: + // USBTRACE("Sector Size is NOT VALID: "); + // goto Fail; + //#endif -FailGetConfDescr: -#ifdef DEBUG_USB_HOST - NotifyFailGetConfDescr(); -#endif + FailSetDevTblEntry: + #ifdef DEBUG_USB_HOST + NotifyFailSetDevTblEntry(); + goto Fail; + #endif -#ifdef DEBUG_USB_HOST -Fail: - NotifyFail(rcode); -#endif - Release(); - return rcode; + FailGetConfDescr: + #ifdef DEBUG_USB_HOST + NotifyFailGetConfDescr(); + #endif + + #ifdef DEBUG_USB_HOST + Fail: + NotifyFail(rcode); + #endif + Release(); + return rcode; } /** @@ -548,46 +530,45 @@ Fail: * @param pep */ void BulkOnly::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto __attribute__((unused)), const USB_ENDPOINT_DESCRIPTOR * pep) { - ErrorMessage (PSTR("Conf.Val"), conf); - ErrorMessage (PSTR("Iface Num"), iface); - ErrorMessage (PSTR("Alt.Set"), alt); - - bConfNum = conf; - - uint8_t index; - -#if 1 - if((pep->bmAttributes & bmUSB_TRANSFER_TYPE) == USB_TRANSFER_TYPE_BULK) { - index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex; - // Fill in the endpoint info structure - epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F); - epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize; - epInfo[index].bmSndToggle = 0; - epInfo[index].bmRcvToggle = 0; - - bNumEP++; - - PrintEndpointDescriptor(pep); - - } -#else - if((pep->bmAttributes & bmUSB_TRANSFER_TYPE) == USB_TRANSFER_TYPE_INTERRUPT && (pep->bEndpointAddress & 0x80) == 0x80) - index = epInterruptInIndex; - else if((pep->bmAttributes & bmUSB_TRANSFER_TYPE) == USB_TRANSFER_TYPE_BULK) - index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex; - else - return; - - // Fill in the endpoint info structure - epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F); - epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize; - epInfo[index].bmSndToggle = 0; - epInfo[index].bmRcvToggle = 0; - - bNumEP++; - - PrintEndpointDescriptor(pep); -#endif + ErrorMessage (PSTR("Conf.Val"), conf); + ErrorMessage (PSTR("Iface Num"), iface); + ErrorMessage (PSTR("Alt.Set"), alt); + + bConfNum = conf; + + uint8_t index; + + #if 1 + if ((pep->bmAttributes & bmUSB_TRANSFER_TYPE) == USB_TRANSFER_TYPE_BULK) { + index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex; + // Fill in the endpoint info structure + epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F); + epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize; + epInfo[index].bmSndToggle = 0; + epInfo[index].bmRcvToggle = 0; + + bNumEP++; + + PrintEndpointDescriptor(pep); + } + #else + if ((pep->bmAttributes & bmUSB_TRANSFER_TYPE) == USB_TRANSFER_TYPE_INTERRUPT && (pep->bEndpointAddress & 0x80) == 0x80) + index = epInterruptInIndex; + else if ((pep->bmAttributes & bmUSB_TRANSFER_TYPE) == USB_TRANSFER_TYPE_BULK) + index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex; + else + return; + + // Fill in the endpoint info structure + epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F); + epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize; + epInfo[index].bmSndToggle = 0; + epInfo[index].bmRcvToggle = 0; + + bNumEP++; + + PrintEndpointDescriptor(pep); + #endif } /** @@ -596,9 +577,9 @@ void BulkOnly::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t * @return */ uint8_t BulkOnly::Release() { - ClearAllEP(); - pUsb->GetAddressPool().FreeAddress(bAddress); - return 0; + ClearAllEP(); + pUsb->GetAddressPool().FreeAddress(bAddress); + return 0; } /** @@ -608,38 +589,37 @@ uint8_t BulkOnly::Release() { * @return true if LUN is ready for use. */ bool BulkOnly::CheckLUN(uint8_t lun) { - uint8_t rcode; - Capacity capacity; - for(uint8_t i = 0; i < 8; i++) capacity.data[i] = 0; - - rcode = ReadCapacity10(lun, (uint8_t*)capacity.data); - if(rcode) { - //printf(">>>>>>>>>>>>>>>>ReadCapacity returned %i\r\n", rcode); - return false; - } - ErrorMessage (PSTR(">>>>>>>>>>>>>>>>CAPACITY OK ON LUN"), lun); - for(uint8_t i = 0; i < 8 /*sizeof (Capacity)*/; i++) - D_PrintHex (capacity.data[i], 0x80); - Notify(PSTR("\r\n\r\n"), 0x80); - // Only 512/1024/2048/4096 are valid values! - uint32_t c = BMAKE32(capacity.data[4], capacity.data[5], capacity.data[6], capacity.data[7]); - if(c != 0x0200LU && c != 0x0400LU && c != 0x0800LU && c != 0x1000LU) { - return false; - } - // Store capacity information. - CurrentSectorSize[lun] = (uint16_t)(c); // & 0xFFFF); - - CurrentCapacity[lun] = BMAKE32(capacity.data[0], capacity.data[1], capacity.data[2], capacity.data[3]) + 1; - if(CurrentCapacity[lun] == /*0xffffffffLU */ 0x01LU || CurrentCapacity[lun] == 0x00LU) { - // Buggy firmware will report 0xffffffff or 0 for no media - if(CurrentCapacity[lun]) - ErrorMessage (PSTR(">>>>>>>>>>>>>>>>BUGGY FIRMWARE. CAPACITY FAIL ON LUN"), lun); - return false; - } - delay(20); - Page3F(lun); - if(!TestUnitReady(lun)) return true; - return false; + uint8_t rcode; + Capacity capacity; + for (uint8_t i = 0; i < 8; i++) capacity.data[i] = 0; + + rcode = ReadCapacity10(lun, (uint8_t*)capacity.data); + if (rcode) { + //printf(">>>>>>>>>>>>>>>>ReadCapacity returned %i\r\n", rcode); + return false; + } + ErrorMessage (PSTR(">>>>>>>>>>>>>>>>CAPACITY OK ON LUN"), lun); + for (uint8_t i = 0; i < 8 /*sizeof (Capacity)*/; i++) + D_PrintHex (capacity.data[i], 0x80); + Notify(PSTR("\r\n\r\n"), 0x80); + + // Only 512/1024/2048/4096 are valid values! + uint32_t c = BMAKE32(capacity.data[4], capacity.data[5], capacity.data[6], capacity.data[7]); + if (c != 0x0200UL && c != 0x0400UL && c != 0x0800UL && c != 0x1000UL) return false; + + // Store capacity information. + CurrentSectorSize[lun] = (uint16_t)(c); // & 0xFFFF); + + CurrentCapacity[lun] = BMAKE32(capacity.data[0], capacity.data[1], capacity.data[2], capacity.data[3]) + 1; + if (CurrentCapacity[lun] == /*0xFFFFFFFFUL */ 0x01UL || CurrentCapacity[lun] == 0x00UL) { + // Buggy firmware will report 0xFFFFFFFF or 0 for no media + if (CurrentCapacity[lun]) + ErrorMessage (PSTR(">>>>>>>>>>>>>>>>BUGGY FIRMWARE. CAPACITY FAIL ON LUN"), lun); + return false; + } + delay(20); + Page3F(lun); + return !TestUnitReady(lun); } /** @@ -648,24 +628,20 @@ bool BulkOnly::CheckLUN(uint8_t lun) { * Scan for media change on all LUNs */ void BulkOnly::CheckMedia() { - for(uint8_t lun = 0; lun <= bMaxLUN; lun++) { - if(TestUnitReady(lun)) { - LUNOk[lun] = false; - continue; - } - if(!LUNOk[lun]) - LUNOk[lun] = CheckLUN(lun); - } -#if 0 - printf("}}}}}}}}}}}}}}}}STATUS "); - for(uint8_t lun = 0; lun <= bMaxLUN; lun++) { - if(LUNOk[lun]) - printf("#"); - else printf("."); - } - printf("\r\n"); -#endif - qNextPollTime = (uint32_t)millis() + 2000; + for (uint8_t lun = 0; lun <= bMaxLUN; lun++) { + if (TestUnitReady(lun)) { + LUNOk[lun] = false; + continue; + } + if (!LUNOk[lun]) LUNOk[lun] = CheckLUN(lun); + } + #if 0 + printf("}}}}}}}}}}}}}}}}STATUS "); + for (uint8_t lun = 0; lun <= bMaxLUN; lun++) + printf(LUNOk[lun] ? "#" : "."); + printf("\r\n"); + #endif + qNextPollTime = (uint32_t)millis() + 2000; } /** @@ -674,17 +650,11 @@ void BulkOnly::CheckMedia() { * @return */ uint8_t BulkOnly::Poll() { - //uint8_t rcode = 0; - - if(!bPollEnable) - return 0; - - if((int32_t)((uint32_t)millis() - qNextPollTime) >= 0L) { - CheckMedia(); - } - //rcode = 0; - - return 0; + //uint8_t rcode = 0; + if (!bPollEnable) return 0; + if ((int32_t)((uint32_t)millis() - qNextPollTime) >= 0L) CheckMedia(); + //rcode = 0; + return 0; } //////////////////////////////////////////////////////////////////////////////// @@ -700,7 +670,7 @@ uint8_t BulkOnly::Poll() { uint8_t BulkOnly::GetMaxLUN(uint8_t *plun) { uint8_t ret = pUsb->ctrlReq(bAddress, 0, bmREQ_MASSIN, MASS_REQ_GET_MAX_LUN, 0, 0, bIface, 1, 1, plun, NULL); - if(ret == hrSTALL) + if (ret == hrSTALL) *plun = 0; return 0; @@ -718,7 +688,7 @@ uint8_t BulkOnly::Inquiry(uint8_t lun, uint16_t bsize, uint8_t *buf) { Notify(PSTR("\r\nInquiry\r\n"), 0x80); Notify(PSTR("---------\r\n"), 0x80); - CDB6_t cdb = CDB6_t(SCSI_CMD_INQUIRY, lun, 0LU, (uint8_t)bsize, 0); + CDB6_t cdb = CDB6_t(SCSI_CMD_INQUIRY, lun, 0UL, (uint8_t)bsize, 0); uint8_t rc = SCSITransaction6(&cdb, bsize, buf, (uint8_t)MASS_CMD_DIR_IN); return rc; @@ -732,7 +702,7 @@ uint8_t BulkOnly::Inquiry(uint8_t lun, uint16_t bsize, uint8_t *buf) { */ uint8_t BulkOnly::TestUnitReady(uint8_t lun) { //SetCurLUN(lun); - if(!bAddress) + if (!bAddress) return MASS_ERR_UNIT_NOT_READY; Notify(PSTR("\r\nTestUnitReady\r\n"), 0x80); @@ -788,7 +758,7 @@ uint8_t BulkOnly::ReadCapacity10(uint8_t lun, uint8_t *buf) { */ uint8_t BulkOnly::Page3F(uint8_t lun) { uint8_t buf[192]; - for(int i = 0; i < 192; i++) { + for (int i = 0; i < 192; i++) { buf[i] = 0x00; } WriteOk[lun] = true; @@ -796,11 +766,11 @@ uint8_t BulkOnly::Page3F(uint8_t lun) { return 0; #endif uint8_t rc = ModeSense6(lun, 0, 0x3f, 0, 192, buf); - if(!rc) { + if (!rc) { WriteOk[lun] = ((buf[2] & 0x80) == 0); Notify(PSTR("Mode Sense: "), 0x80); - for(int i = 0; i < 4; i++) { - D_PrintHex (buf[i], 0x80); + for (int i = 0; i < 4; i++) { + D_PrintHex (buf[i], 0x80); Notify(PSTR(" "), 0x80); } Notify(PSTR("\r\n"), 0x80); @@ -820,7 +790,7 @@ uint8_t BulkOnly::RequestSense(uint8_t lun, uint16_t size, uint8_t *buf) { Notify(PSTR("\r\nRequestSense\r\n"), 0x80); Notify(PSTR("----------------\r\n"), 0x80); - CDB6_t cdb = CDB6_t(SCSI_CMD_REQUEST_SENSE, lun, 0LU, (uint8_t)size, 0); + CDB6_t cdb = CDB6_t(SCSI_CMD_REQUEST_SENSE, lun, 0UL, (uint8_t)size, 0); CommandBlockWrapper cbw = CommandBlockWrapper(++dCBWTag, (uint32_t)size, &cdb, (uint8_t)MASS_CMD_DIR_IN); //SetCurLUN(lun); return Transaction(&cbw, size, buf); @@ -838,17 +808,17 @@ uint8_t BulkOnly::RequestSense(uint8_t lun, uint16_t size, uint8_t *buf) { * @return */ uint8_t BulkOnly::ClearEpHalt(uint8_t index) { - if(index == 0) + if (index == 0) return 0; uint8_t ret = 0; - while((ret = (pUsb->ctrlReq(bAddress, 0, USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT, USB_REQUEST_CLEAR_FEATURE, USB_FEATURE_ENDPOINT_HALT, 0, ((index == epDataInIndex) ? (0x80 | epInfo[index].epAddr) : epInfo[index].epAddr), 0, 0, NULL, NULL)) == 0x01)) + while ((ret = (pUsb->ctrlReq(bAddress, 0, USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT, USB_REQUEST_CLEAR_FEATURE, USB_FEATURE_ENDPOINT_HALT, 0, ((index == epDataInIndex) ? (0x80 | epInfo[index].epAddr) : epInfo[index].epAddr), 0, 0, NULL, NULL)) == 0x01)) delay(6); - if(ret) { - ErrorMessage (PSTR("ClearEpHalt"), ret); - ErrorMessage (PSTR("EP"), ((index == epDataInIndex) ? (0x80 | epInfo[index].epAddr) : epInfo[index].epAddr)); + if (ret) { + ErrorMessage (PSTR("ClearEpHalt"), ret); + ErrorMessage (PSTR("EP"), ((index == epDataInIndex) ? (0x80 | epInfo[index].epAddr) : epInfo[index].epAddr)); return ret; } epInfo[index].bmSndToggle = 0; @@ -861,7 +831,7 @@ uint8_t BulkOnly::ClearEpHalt(uint8_t index) { * */ void BulkOnly::Reset() { - while(pUsb->ctrlReq(bAddress, 0, bmREQ_MASSOUT, MASS_REQ_BOMSR, 0, 0, bIface, 0, 0, NULL, NULL) == 0x01) delay(6); + while (pUsb->ctrlReq(bAddress, 0, bmREQ_MASSOUT, MASS_REQ_BOMSR, 0, 0, bIface, 0, 0, NULL, NULL) == 0x01) delay(6); } /** @@ -889,29 +859,29 @@ uint8_t BulkOnly::ResetRecovery() { * Clear all EP data and clear all LUN status */ void BulkOnly::ClearAllEP() { - for(uint8_t i = 0; i < MASS_MAX_ENDPOINTS; i++) { - epInfo[i].epAddr = 0; - epInfo[i].maxPktSize = (i) ? 0 : 8; - epInfo[i].bmSndToggle = 0; - epInfo[i].bmRcvToggle = 0; - epInfo[i].bmNakPower = USB_NAK_DEFAULT; - } - - for(uint8_t i = 0; i < MASS_MAX_SUPPORTED_LUN; i++) { - LUNOk[i] = false; - WriteOk[i] = false; - CurrentCapacity[i] = 0lu; - CurrentSectorSize[i] = 0; - } - - bIface = 0; - bNumEP = 1; - bAddress = 0; - qNextPollTime = 0; - bPollEnable = false; - bLastUsbError = 0; - bMaxLUN = 0; - bTheLUN = 0; + for (uint8_t i = 0; i < MASS_MAX_ENDPOINTS; i++) { + epInfo[i].epAddr = 0; + epInfo[i].maxPktSize = (i) ? 0 : 8; + epInfo[i].bmSndToggle = 0; + epInfo[i].bmRcvToggle = 0; + epInfo[i].bmNakPower = USB_NAK_DEFAULT; + } + + for (uint8_t i = 0; i < MASS_MAX_SUPPORTED_LUN; i++) { + LUNOk[i] = false; + WriteOk[i] = false; + CurrentCapacity[i] = 0UL; + CurrentSectorSize[i] = 0; + } + + bIface = 0; + bNumEP = 1; + bAddress = 0; + qNextPollTime = 0; + bPollEnable = false; + bLastUsbError = 0; + bMaxLUN = 0; + bTheLUN = 0; } /** @@ -922,15 +892,15 @@ void BulkOnly::ClearAllEP() { * @return */ bool BulkOnly::IsValidCSW(CommandStatusWrapper *pcsw, CommandBlockWrapperBase *pcbw) { - if(pcsw->dCSWSignature != MASS_CSW_SIGNATURE) { - Notify(PSTR("CSW:Sig error\r\n"), 0x80); - return false; - } - if(pcsw->dCSWTag != pcbw->dCBWTag) { - Notify(PSTR("CSW:Wrong tag\r\n"), 0x80); - return false; - } - return true; + if (pcsw->dCSWSignature != MASS_CSW_SIGNATURE) { + Notify(PSTR("CSW:Sig error\r\n"), 0x80); + return false; + } + if (pcsw->dCSWTag != pcbw->dCBWTag) { + Notify(PSTR("CSW:Wrong tag\r\n"), 0x80); + return false; + } + return true; } /** @@ -941,65 +911,56 @@ bool BulkOnly::IsValidCSW(CommandStatusWrapper *pcsw, CommandBlockWrapperBase *p * @return */ uint8_t BulkOnly::HandleUsbError(uint8_t error, uint8_t index) { - uint8_t count = 3; - - bLastUsbError = error; - //if (error) - //ClearEpHalt(index); - while(error && count) { - if(error != hrSUCCESS) { - ErrorMessage (PSTR("USB Error"), error); - ErrorMessage (PSTR("Index"), index); - } - switch(error) { - // case hrWRONGPID: - case hrSUCCESS: - return MASS_ERR_SUCCESS; - case hrBUSY: - // SIE is busy, just hang out and try again. - return MASS_ERR_UNIT_BUSY; - case hrTIMEOUT: - case hrJERR: return MASS_ERR_DEVICE_DISCONNECTED; - case hrSTALL: - if(index == 0) - return MASS_ERR_STALL; - ClearEpHalt(index); - if(index != epDataInIndex) - return MASS_ERR_WRITE_STALL; - return MASS_ERR_STALL; - - case hrNAK: - if(index == 0) - return MASS_ERR_UNIT_BUSY; - return MASS_ERR_UNIT_BUSY; - - case hrTOGERR: - // Handle a very super rare corner case, where toggles become de-synched. - // I have only ran into one device that has this firmware bug, and this is - // the only clean way to get back into sync with the buggy device firmware. - // --AJK - if(bAddress && bConfNum) { - error = pUsb->setConf(bAddress, 0, bConfNum); - - if(error) - break; - } - return MASS_ERR_SUCCESS; - default: - ErrorMessage (PSTR("\r\nUSB"), error); - return MASS_ERR_GENERAL_USB_ERROR; - } - count--; - } // while - - return ((error && !count) ? MASS_ERR_GENERAL_USB_ERROR : MASS_ERR_SUCCESS); + uint8_t count = 3; + + bLastUsbError = error; + //if (error) + //ClearEpHalt(index); + while (error && count) { + if (error != hrSUCCESS) { + ErrorMessage (PSTR("USB Error"), error); + ErrorMessage (PSTR("Index"), index); + } + switch (error) { + // case hrWRONGPID: + case hrSUCCESS: return MASS_ERR_SUCCESS; + case hrBUSY: return MASS_ERR_UNIT_BUSY; // SIE is busy, just hang out and try again. + case hrTIMEOUT: + case hrJERR: return MASS_ERR_DEVICE_DISCONNECTED; + case hrSTALL: + if (index) { + ClearEpHalt(index); + return (index == epDataInIndex) ? MASS_ERR_STALL : MASS_ERR_WRITE_STALL; + } + return MASS_ERR_STALL; + + case hrNAK: + return index ? MASS_ERR_UNIT_BUSY : MASS_ERR_UNIT_BUSY; + + case hrTOGERR: + // Handle a super rare corner case, where toggles become de-synced. + // I've only run into one device that has this firmware bug, and this is + // the only clean way to get back into sync with the buggy device firmware. + // --AJK + if (bAddress && bConfNum) { + error = pUsb->setConf(bAddress, 0, bConfNum); + if (error) break; + } + return MASS_ERR_SUCCESS; + default: + ErrorMessage (PSTR("\r\nUSB"), error); + return MASS_ERR_GENERAL_USB_ERROR; + } + count--; + } // while + + return ((error && !count) ? MASS_ERR_GENERAL_USB_ERROR : MASS_ERR_SUCCESS); } #if MS_WANT_PARSER - -uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void *buf) { - return Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void *buf, 0); -} + uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void *buf) { + return Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void *buf, 0); + } #endif /** @@ -1012,101 +973,100 @@ uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void * @return */ uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void *buf -#if MS_WANT_PARSER - , uint8_t flags -#endif - ) { - -#if MS_WANT_PARSER - uint16_t bytes = (pcbw->dCBWDataTransferLength > buf_size) ? buf_size : pcbw->dCBWDataTransferLength; - printf("Transfersize %i\r\n", bytes); - delay(1000); - - bool callback = (flags & MASS_TRANS_FLG_CALLBACK) == MASS_TRANS_FLG_CALLBACK; -#else - uint16_t bytes = buf_size; -#endif - bool write = (pcbw->bmCBWFlags & MASS_CMD_DIR_IN) != MASS_CMD_DIR_IN; - uint8_t ret = 0; - uint8_t usberr; - CommandStatusWrapper csw; // up here, we allocate ahead to save cpu cycles. - SetCurLUN(pcbw->bmCBWLUN); - ErrorMessage (PSTR("CBW.dCBWTag"), pcbw->dCBWTag); - - while((usberr = pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, sizeof (CommandBlockWrapper), (uint8_t*)pcbw)) == hrBUSY) delay(1); - + #if MS_WANT_PARSER + , uint8_t flags + #endif +) { + #if MS_WANT_PARSER + uint16_t bytes = (pcbw->dCBWDataTransferLength > buf_size) ? buf_size : pcbw->dCBWDataTransferLength; + printf("Transfersize %i\r\n", bytes); + delay(1000); + + bool callback = (flags & MASS_TRANS_FLG_CALLBACK) == MASS_TRANS_FLG_CALLBACK; + #else + uint16_t bytes = buf_size; + #endif + + bool write = (pcbw->bmCBWFlags & MASS_CMD_DIR_IN) != MASS_CMD_DIR_IN; + uint8_t ret = 0; + uint8_t usberr; + CommandStatusWrapper csw; // up here, we allocate ahead to save cpu cycles. + SetCurLUN(pcbw->bmCBWLUN); + ErrorMessage (PSTR("CBW.dCBWTag"), pcbw->dCBWTag); + + while ((usberr = pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, sizeof (CommandBlockWrapper), (uint8_t*)pcbw)) == hrBUSY) delay(1); + + ret = HandleUsbError(usberr, epDataOutIndex); + //ret = HandleUsbError(pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, sizeof (CommandBlockWrapper), (uint8_t*)pcbw), epDataOutIndex); + if (ret) + ErrorMessage (PSTR("============================ CBW"), ret); + else { + if (bytes) { + if (!write) { + #if MS_WANT_PARSER + if (callback) { + uint8_t rbuf[bytes]; + while ((usberr = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &bytes, rbuf)) == hrBUSY) delay(1); + if (usberr == hrSUCCESS) ((USBReadParser*)buf)->Parse(bytes, rbuf, 0); + } + else + #endif + { + while ((usberr = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &bytes, (uint8_t*)buf)) == hrBUSY) delay(1); + } + ret = HandleUsbError(usberr, epDataInIndex); + } + else { + while ((usberr = pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, bytes, (uint8_t*)buf)) == hrBUSY) delay(1); ret = HandleUsbError(usberr, epDataOutIndex); - //ret = HandleUsbError(pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, sizeof (CommandBlockWrapper), (uint8_t*)pcbw), epDataOutIndex); - if(ret) { - ErrorMessage (PSTR("============================ CBW"), ret); - } else { - if(bytes) { - if(!write) { -#if MS_WANT_PARSER - if(callback) { - uint8_t rbuf[bytes]; - while((usberr = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &bytes, rbuf)) == hrBUSY) delay(1); - if(usberr == hrSUCCESS) ((USBReadParser*)buf)->Parse(bytes, rbuf, 0); - } else { -#endif - while((usberr = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &bytes, (uint8_t*)buf)) == hrBUSY) delay(1); -#if MS_WANT_PARSER - - } -#endif - ret = HandleUsbError(usberr, epDataInIndex); - } else { - while((usberr = pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, bytes, (uint8_t*)buf)) == hrBUSY) delay(1); - ret = HandleUsbError(usberr, epDataOutIndex); - } - if(ret) { - ErrorMessage (PSTR("============================ DAT"), ret); - } - } - } - - { - bytes = sizeof (CommandStatusWrapper); - int tries = 2; - while(tries--) { - while((usberr = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &bytes, (uint8_t*) & csw)) == hrBUSY) delay(1); - if(!usberr) break; - ClearEpHalt(epDataInIndex); - if(tries) ResetRecovery(); - } - if(!ret) { - Notify(PSTR("CBW:\t\tOK\r\n"), 0x80); - Notify(PSTR("Data Stage:\tOK\r\n"), 0x80); - } else { - // Throw away csw, IT IS NOT OF ANY USE. - ResetRecovery(); - return ret; - } - ret = HandleUsbError(usberr, epDataInIndex); - if(ret) { - ErrorMessage (PSTR("============================ CSW"), ret); - } - if(usberr == hrSUCCESS) { - if(IsValidCSW(&csw, pcbw)) { - //ErrorMessage (PSTR("CSW.dCBWTag"), csw.dCSWTag); - //ErrorMessage (PSTR("bCSWStatus"), csw.bCSWStatus); - //ErrorMessage (PSTR("dCSWDataResidue"), csw.dCSWDataResidue); - Notify(PSTR("CSW:\t\tOK\r\n\r\n"), 0x80); - return csw.bCSWStatus; - } else { - // NOTE! Sometimes this is caused by the reported residue being wrong. - // Get a different device. It isn't compliant, and should have never passed Q&A. - // I own one... 05e3:0701 Genesys Logic, Inc. USB 2.0 IDE Adapter. - // Other devices that exhibit this behavior exist in the wild too. - // Be sure to check quirks in the Linux source code before reporting a bug. --xxxajk - Notify(PSTR("Invalid CSW\r\n"), 0x80); - ResetRecovery(); - //return MASS_ERR_SUCCESS; - return MASS_ERR_INVALID_CSW; - } - } - } - return ret; + } + if (ret) ErrorMessage (PSTR("============================ DAT"), ret); + } + } + + bytes = sizeof (CommandStatusWrapper); + int tries = 2; + while (tries--) { + while ((usberr = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &bytes, (uint8_t*) & csw)) == hrBUSY) delay(1); + if (!usberr) break; + ClearEpHalt(epDataInIndex); + if (tries) ResetRecovery(); + } + + if (!ret) { + Notify(PSTR("CBW:\t\tOK\r\n"), 0x80); + Notify(PSTR("Data Stage:\tOK\r\n"), 0x80); + } + else { + // Throw away csw, IT IS NOT OF ANY USE. + ResetRecovery(); + return ret; + } + + ret = HandleUsbError(usberr, epDataInIndex); + if (ret) ErrorMessage (PSTR("============================ CSW"), ret); + + if (usberr == hrSUCCESS) { + if (IsValidCSW(&csw, pcbw)) { + //ErrorMessage (PSTR("CSW.dCBWTag"), csw.dCSWTag); + //ErrorMessage (PSTR("bCSWStatus"), csw.bCSWStatus); + //ErrorMessage (PSTR("dCSWDataResidue"), csw.dCSWDataResidue); + Notify(PSTR("CSW:\t\tOK\r\n\r\n"), 0x80); + return csw.bCSWStatus; + } + else { + // NOTE! Sometimes this is caused by the reported residue being wrong. + // Get a different device. It isn't compliant, and should have never passed Q&A. + // I own one... 05e3:0701 Genesys Logic, Inc. USB 2.0 IDE Adapter. + // Other devices that exhibit this behavior exist in the wild too. + // Be sure to check quirks in the Linux source code before reporting a bug. --xxxajk + Notify(PSTR("Invalid CSW\r\n"), 0x80); + ResetRecovery(); + //return MASS_ERR_SUCCESS; + return MASS_ERR_INVALID_CSW; + } + } + return ret; } /** @@ -1116,11 +1076,10 @@ uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void * @return */ uint8_t BulkOnly::SetCurLUN(uint8_t lun) { - if(lun > bMaxLUN) - return MASS_ERR_INVALID_LUN; - bTheLUN = lun; - return MASS_ERR_SUCCESS; -}; + if (lun > bMaxLUN) return MASS_ERR_INVALID_LUN; + bTheLUN = lun; + return MASS_ERR_SUCCESS; +} /** * For driver use only. @@ -1129,83 +1088,78 @@ uint8_t BulkOnly::SetCurLUN(uint8_t lun) { * @return */ uint8_t BulkOnly::HandleSCSIError(uint8_t status) { - uint8_t ret = 0; + uint8_t ret = 0; - switch(status) { - case 0: return MASS_ERR_SUCCESS; - - case 2: - ErrorMessage (PSTR("Phase Error"), status); - ErrorMessage (PSTR("LUN"), bTheLUN); - ResetRecovery(); - return MASS_ERR_GENERAL_SCSI_ERROR; - - case 1: - ErrorMessage (PSTR("SCSI Error"), status); - ErrorMessage (PSTR("LUN"), bTheLUN); - RequestSenseResponce rsp; - - ret = RequestSense(bTheLUN, sizeof (RequestSenseResponce), (uint8_t*) & rsp); - - if(ret) { - return MASS_ERR_GENERAL_SCSI_ERROR; - } - ErrorMessage (PSTR("Response Code"), rsp.bResponseCode); - if(rsp.bResponseCode & 0x80) { - Notify(PSTR("Information field: "), 0x80); - for(int i = 0; i < 4; i++) { - D_PrintHex (rsp.CmdSpecificInformation[i], 0x80); - Notify(PSTR(" "), 0x80); - } - Notify(PSTR("\r\n"), 0x80); - } - ErrorMessage (PSTR("Sense Key"), rsp.bmSenseKey); - ErrorMessage (PSTR("Add Sense Code"), rsp.bAdditionalSenseCode); - ErrorMessage (PSTR("Add Sense Qual"), rsp.bAdditionalSenseQualifier); - // warning, this is not testing ASQ, only SK and ASC. - switch(rsp.bmSenseKey) { - case SCSI_S_UNIT_ATTENTION: - switch(rsp.bAdditionalSenseCode) { - case SCSI_ASC_MEDIA_CHANGED: - return MASS_ERR_MEDIA_CHANGED; - default: - return MASS_ERR_UNIT_NOT_READY; - } - case SCSI_S_NOT_READY: - switch(rsp.bAdditionalSenseCode) { - case SCSI_ASC_MEDIUM_NOT_PRESENT: - return MASS_ERR_NO_MEDIA; - default: - return MASS_ERR_UNIT_NOT_READY; - } - case SCSI_S_ILLEGAL_REQUEST: - switch(rsp.bAdditionalSenseCode) { - case SCSI_ASC_LBA_OUT_OF_RANGE: - return MASS_ERR_BAD_LBA; - default: - return MASS_ERR_CMD_NOT_SUPPORTED; - } - default: - return MASS_ERR_GENERAL_SCSI_ERROR; - } - - // case 4: return MASS_ERR_UNIT_BUSY; // Busy means retry later. - // case 0x05/0x14: we stalled out - // case 0x15/0x16: we naked out. - default: - ErrorMessage (PSTR("Gen SCSI Err"), status); - ErrorMessage (PSTR("LUN"), bTheLUN); - return status; - } // switch -} + switch (status) { + case 0: return MASS_ERR_SUCCESS; + case 2: + ErrorMessage (PSTR("Phase Error"), status); + ErrorMessage (PSTR("LUN"), bTheLUN); + ResetRecovery(); + return MASS_ERR_GENERAL_SCSI_ERROR; -//////////////////////////////////////////////////////////////////////////////// + case 1: + ErrorMessage (PSTR("SCSI Error"), status); + ErrorMessage (PSTR("LUN"), bTheLUN); + RequestSenseResponce rsp; + ret = RequestSense(bTheLUN, sizeof (RequestSenseResponce), (uint8_t*) & rsp); -// Debugging code + if (ret) return MASS_ERR_GENERAL_SCSI_ERROR; + + ErrorMessage (PSTR("Response Code"), rsp.bResponseCode); + if (rsp.bResponseCode & 0x80) { + Notify(PSTR("Information field: "), 0x80); + for (int i = 0; i < 4; i++) { + D_PrintHex (rsp.CmdSpecificInformation[i], 0x80); + Notify(PSTR(" "), 0x80); + } + Notify(PSTR("\r\n"), 0x80); + } + ErrorMessage (PSTR("Sense Key"), rsp.bmSenseKey); + ErrorMessage (PSTR("Add Sense Code"), rsp.bAdditionalSenseCode); + ErrorMessage (PSTR("Add Sense Qual"), rsp.bAdditionalSenseQualifier); + // warning, this is not testing ASQ, only SK and ASC. + switch (rsp.bmSenseKey) { + case SCSI_S_UNIT_ATTENTION: + switch (rsp.bAdditionalSenseCode) { + case SCSI_ASC_MEDIA_CHANGED: + return MASS_ERR_MEDIA_CHANGED; + default: + return MASS_ERR_UNIT_NOT_READY; + } + case SCSI_S_NOT_READY: + switch (rsp.bAdditionalSenseCode) { + case SCSI_ASC_MEDIUM_NOT_PRESENT: + return MASS_ERR_NO_MEDIA; + default: + return MASS_ERR_UNIT_NOT_READY; + } + case SCSI_S_ILLEGAL_REQUEST: + switch (rsp.bAdditionalSenseCode) { + case SCSI_ASC_LBA_OUT_OF_RANGE: + return MASS_ERR_BAD_LBA; + default: + return MASS_ERR_CMD_NOT_SUPPORTED; + } + default: + return MASS_ERR_GENERAL_SCSI_ERROR; + } + + // case 4: return MASS_ERR_UNIT_BUSY; // Busy means retry later. + // case 0x05/0x14: we stalled out + // case 0x15/0x16: we naked out. + default: + ErrorMessage (PSTR("Gen SCSI Err"), status); + ErrorMessage (PSTR("LUN"), bTheLUN); + return status; + } // switch +} +//////////////////////////////////////////////////////////////////////////////// +// Debugging code //////////////////////////////////////////////////////////////////////////////// /** @@ -1213,20 +1167,20 @@ uint8_t BulkOnly::HandleSCSIError(uint8_t status) { * @param ep_ptr */ void BulkOnly::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR * ep_ptr) { - Notify(PSTR("Endpoint descriptor:"), 0x80); - Notify(PSTR("\r\nLength:\t\t"), 0x80); - D_PrintHex (ep_ptr->bLength, 0x80); - Notify(PSTR("\r\nType:\t\t"), 0x80); - D_PrintHex (ep_ptr->bDescriptorType, 0x80); - Notify(PSTR("\r\nAddress:\t"), 0x80); - D_PrintHex (ep_ptr->bEndpointAddress, 0x80); - Notify(PSTR("\r\nAttributes:\t"), 0x80); - D_PrintHex (ep_ptr->bmAttributes, 0x80); - Notify(PSTR("\r\nMaxPktSize:\t"), 0x80); - D_PrintHex (ep_ptr->wMaxPacketSize, 0x80); - Notify(PSTR("\r\nPoll Intrv:\t"), 0x80); - D_PrintHex (ep_ptr->bInterval, 0x80); - Notify(PSTR("\r\n"), 0x80); + Notify(PSTR("Endpoint descriptor:"), 0x80); + Notify(PSTR("\r\nLength:\t\t"), 0x80); + D_PrintHex (ep_ptr->bLength, 0x80); + Notify(PSTR("\r\nType:\t\t"), 0x80); + D_PrintHex (ep_ptr->bDescriptorType, 0x80); + Notify(PSTR("\r\nAddress:\t"), 0x80); + D_PrintHex (ep_ptr->bEndpointAddress, 0x80); + Notify(PSTR("\r\nAttributes:\t"), 0x80); + D_PrintHex (ep_ptr->bmAttributes, 0x80); + Notify(PSTR("\r\nMaxPktSize:\t"), 0x80); + D_PrintHex (ep_ptr->wMaxPacketSize, 0x80); + Notify(PSTR("\r\nPoll Intrv:\t"), 0x80); + D_PrintHex (ep_ptr->bInterval, 0x80); + Notify(PSTR("\r\n"), 0x80); } //////////////////////////////////////////////////////////////////////////////// @@ -1235,31 +1189,31 @@ void BulkOnly::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR * ep_ptr) { /* We won't be needing this... */ uint8_t BulkOnly::Read(uint8_t lun __attribute__((unused)), uint32_t addr __attribute__((unused)), uint16_t bsize __attribute__((unused)), uint8_t blocks __attribute__((unused)), USBReadParser * prs __attribute__((unused))) { -#if MS_WANT_PARSER - if(!LUNOk[lun]) return MASS_ERR_NO_MEDIA; - Notify(PSTR("\r\nRead (With parser)\r\n"), 0x80); - Notify(PSTR("---------\r\n"), 0x80); - - CommandBlockWrapper cbw = CommandBlockWrapper(); - - cbw.dCBWSignature = MASS_CBW_SIGNATURE; - cbw.dCBWTag = ++dCBWTag; - cbw.dCBWDataTransferLength = ((uint32_t)bsize * blocks); - cbw.bmCBWFlags = MASS_CMD_DIR_IN, - cbw.bmCBWLUN = lun; - cbw.bmCBWCBLength = 10; - - cbw.CBWCB[0] = SCSI_CMD_READ_10; - cbw.CBWCB[8] = blocks; - cbw.CBWCB[2] = ((addr >> 24) & 0xff); - cbw.CBWCB[3] = ((addr >> 16) & 0xff); - cbw.CBWCB[4] = ((addr >> 8) & 0xff); - cbw.CBWCB[5] = (addr & 0xff); - - return HandleSCSIError(Transaction(&cbw, bsize, prs, 1)); -#else - return MASS_ERR_NOT_IMPLEMENTED; -#endif + #if MS_WANT_PARSER + if (!LUNOk[lun]) return MASS_ERR_NO_MEDIA; + Notify(PSTR("\r\nRead (With parser)\r\n"), 0x80); + Notify(PSTR("---------\r\n"), 0x80); + + CommandBlockWrapper cbw = CommandBlockWrapper(); + + cbw.dCBWSignature = MASS_CBW_SIGNATURE; + cbw.dCBWTag = ++dCBWTag; + cbw.dCBWDataTransferLength = ((uint32_t)bsize * blocks); + cbw.bmCBWFlags = MASS_CMD_DIR_IN, + cbw.bmCBWLUN = lun; + cbw.bmCBWCBLength = 10; + + cbw.CBWCB[0] = SCSI_CMD_READ_10; + cbw.CBWCB[8] = blocks; + cbw.CBWCB[2] = ((addr >> 24) & 0xff); + cbw.CBWCB[3] = ((addr >> 16) & 0xff); + cbw.CBWCB[4] = ((addr >> 8) & 0xff); + cbw.CBWCB[5] = (addr & 0xff); + + return HandleSCSIError(Transaction(&cbw, bsize, prs, 1)); + #else + return MASS_ERR_NOT_IMPLEMENTED; + #endif } #endif // USB_FLASH_DRIVE_SUPPORT diff --git a/Marlin/src/sd/usb_flashdrive/lib/masstorage.h b/Marlin/src/sd/usb_flashdrive/lib/masstorage.h index 865362d2f..09b82fdb9 100644 --- a/Marlin/src/sd/usb_flashdrive/lib/masstorage.h +++ b/Marlin/src/sd/usb_flashdrive/lib/masstorage.h @@ -408,7 +408,7 @@ public: CommandBlockWrapper() : CommandBlockWrapperBase(0, 0, 0), bmReserved1(0), bmReserved2(0) { - for(int i = 0; i < 16; i++) CBWCB[i] = 0; + for (int i = 0; i < 16; i++) CBWCB[i] = 0; } // Generic Wrap, CDB zeroed. @@ -416,7 +416,7 @@ public: CommandBlockWrapper(uint32_t tag, uint32_t xflen, uint8_t flgs, uint8_t lu, uint8_t cmdlen, uint8_t cmd) : CommandBlockWrapperBase(tag, xflen, flgs), bmCBWLUN(lu), bmReserved1(0), bmCBWCBLength(cmdlen), bmReserved2(0) { - for(int i = 0; i < 16; i++) CBWCB[i] = 0; + for (int i = 0; i < 16; i++) CBWCB[i] = 0; // Type punning can cause optimization problems and bugs. // Using reinterpret_cast to a dreinterpretifferent object is the proper way to do this. //(((BASICCDB_t *) CBWCB)->LUN) = cmd; @@ -493,27 +493,17 @@ protected: bool WriteOk[MASS_MAX_SUPPORTED_LUN]; void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr); - // Additional Initialization Method for Subclasses - virtual uint8_t OnInit() { - return 0; - }; + virtual uint8_t OnInit() { return 0; } public: BulkOnly(USB *p); - uint8_t GetLastUsbError() { - return bLastUsbError; - }; + uint8_t GetLastUsbError() { return bLastUsbError; }; - uint8_t GetbMaxLUN() { - return bMaxLUN; // Max LUN - } - - uint8_t GetbTheLUN() { - return bTheLUN; // Active LUN - } + uint8_t GetbMaxLUN() { return bMaxLUN; } // Max LUN + uint8_t GetbTheLUN() { return bTheLUN; } // Active LUN bool WriteProtected(uint8_t lun); uint8_t MediaCTL(uint8_t lun, uint8_t ctl); @@ -533,16 +523,12 @@ public: uint8_t Release(); uint8_t Poll(); - virtual uint8_t GetAddress() { - return bAddress; - }; + virtual uint8_t GetAddress() { return bAddress; } // UsbConfigXtracter implementation void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep); - virtual bool DEVCLASSOK(uint8_t klass) { - return (klass == USB_CLASS_MASS_STORAGE); - } + virtual bool DEVCLASSOK(uint8_t klass) { return klass == USB_CLASS_MASS_STORAGE; } uint8_t SCSITransaction6(CDB6_t *cdb, uint16_t buf_size, void *buf, uint8_t dir); uint8_t SCSITransaction10(CDB10_t *cdb, uint16_t buf_size, void *buf, uint8_t dir); @@ -573,5 +559,4 @@ private: uint8_t Transaction(CommandBlockWrapper *cbw, uint16_t bsize, void *buf); uint8_t HandleUsbError(uint8_t error, uint8_t index); uint8_t HandleSCSIError(uint8_t status); - }; diff --git a/Marlin/src/sd/usb_flashdrive/lib/max3421e.h b/Marlin/src/sd/usb_flashdrive/lib/max3421e.h index 6c1d7573e..35011f55f 100644 --- a/Marlin/src/sd/usb_flashdrive/lib/max3421e.h +++ b/Marlin/src/sd/usb_flashdrive/lib/max3421e.h @@ -22,11 +22,11 @@ * Web : http://www.circuitsathome.com * e-mail : support@circuitsathome.com */ -#if !defined(_usb_h_) || defined(_max3421e_h_) -#error "Never include max3421e.h directly; include Usb.h instead" -#else +#pragma once -#define _max3421e_h_ +#ifndef _usb_h_ + #error "Never include max3421e.h directly; include Usb.h instead" +#endif /* MAX3421E register/bit names and bitmasks */ @@ -231,6 +231,3 @@ #define MODE_FS_HOST (bmDPPULLDN|bmDMPULLDN|bmHOST|bmSOFKAENAB) #define MODE_LS_HOST (bmDPPULLDN|bmDMPULLDN|bmHOST|bmLOWSPEED|bmSOFKAENAB) - - -#endif //_max3421e_h_ diff --git a/Marlin/src/sd/usb_flashdrive/lib/message.cpp b/Marlin/src/sd/usb_flashdrive/lib/message.cpp index 9c896a3e0..3148afb5b 100644 --- a/Marlin/src/sd/usb_flashdrive/lib/message.cpp +++ b/Marlin/src/sd/usb_flashdrive/lib/message.cpp @@ -35,97 +35,94 @@ int UsbDEBUGlvl = 0x80; void E_Notifyc(char c, int lvl) { - if(UsbDEBUGlvl < lvl) return; -#if defined(ARDUINO) && ARDUINO >=100 - USB_HOST_SERIAL.print(c); -#else - USB_HOST_SERIAL.print(c, BYTE); -#endif - //USB_HOST_SERIAL.flush(); + if (UsbDEBUGlvl < lvl) return; + USB_HOST_SERIAL.print(c + #if !defined(ARDUINO) || ARDUINO < 100 + , BYTE + #endif + ); + //USB_HOST_SERIAL.flush(); } void E_Notify(char const * msg, int lvl) { - if(UsbDEBUGlvl < lvl) return; - if(!msg) return; - char c; - - while((c = pgm_read_byte(msg++))) E_Notifyc(c, lvl); + if (UsbDEBUGlvl < lvl) return; + if (!msg) return; + while (const char c = pgm_read_byte(msg++)) E_Notifyc(c, lvl); } void E_NotifyStr(char const * msg, int lvl) { - if(UsbDEBUGlvl < lvl) return; - if(!msg) return; - char c; - - while((c = *msg++)) E_Notifyc(c, lvl); + if (UsbDEBUGlvl < lvl) return; + if (!msg) return; + while (const char c = *msg++) E_Notifyc(c, lvl); } void E_Notify(uint8_t b, int lvl) { - if(UsbDEBUGlvl < lvl) return; -#if defined(ARDUINO) && ARDUINO >=100 - USB_HOST_SERIAL.print(b); -#else - USB_HOST_SERIAL.print(b, DEC); -#endif - //USB_HOST_SERIAL.flush(); + if (UsbDEBUGlvl < lvl) return; + USB_HOST_SERIAL.print(b + #if !defined(ARDUINO) || ARDUINO < 100 + , DEC + #endif + ); + //USB_HOST_SERIAL.flush(); } void E_Notify(double d, int lvl) { - if(UsbDEBUGlvl < lvl) return; - USB_HOST_SERIAL.print(d); - //USB_HOST_SERIAL.flush(); + if (UsbDEBUGlvl < lvl) return; + USB_HOST_SERIAL.print(d); + //USB_HOST_SERIAL.flush(); } #ifdef DEBUG_USB_HOST -void NotifyFailGetDevDescr(void) { - Notify(PSTR("\r\ngetDevDescr "), 0x80); -} + void NotifyFailGetDevDescr(void) { + Notify(PSTR("\r\ngetDevDescr "), 0x80); + } -void NotifyFailSetDevTblEntry(void) { - Notify(PSTR("\r\nsetDevTblEn "), 0x80); -} + void NotifyFailSetDevTblEntry(void) { + Notify(PSTR("\r\nsetDevTblEn "), 0x80); + } -void NotifyFailGetConfDescr(void) { - Notify(PSTR("\r\ngetConf "), 0x80); -} + void NotifyFailGetConfDescr(void) { + Notify(PSTR("\r\ngetConf "), 0x80); + } -void NotifyFailSetConfDescr(void) { - Notify(PSTR("\r\nsetConf "), 0x80); -} + void NotifyFailSetConfDescr(void) { + Notify(PSTR("\r\nsetConf "), 0x80); + } -void NotifyFailGetDevDescr(uint8_t reason) { - NotifyFailGetDevDescr(); - NotifyFail(reason); -} + void NotifyFailGetDevDescr(uint8_t reason) { + NotifyFailGetDevDescr(); + NotifyFail(reason); + } -void NotifyFailSetDevTblEntry(uint8_t reason) { - NotifyFailSetDevTblEntry(); - NotifyFail(reason); + void NotifyFailSetDevTblEntry(uint8_t reason) { + NotifyFailSetDevTblEntry(); + NotifyFail(reason); -} + } -void NotifyFailGetConfDescr(uint8_t reason) { - NotifyFailGetConfDescr(); - NotifyFail(reason); -} + void NotifyFailGetConfDescr(uint8_t reason) { + NotifyFailGetConfDescr(); + NotifyFail(reason); + } -void NotifyFailSetConfDescr(uint8_t reason) { - NotifyFailSetConfDescr(); - NotifyFail(reason); -} + void NotifyFailSetConfDescr(uint8_t reason) { + NotifyFailSetConfDescr(); + NotifyFail(reason); + } -void NotifyFailUnknownDevice(uint16_t VID, uint16_t PID) { - Notify(PSTR("\r\nUnknown Device Connected - VID: "), 0x80); - D_PrintHex (VID, 0x80); - Notify(PSTR(" PID: "), 0x80); - D_PrintHex (PID, 0x80); -} + void NotifyFailUnknownDevice(uint16_t VID, uint16_t PID) { + Notify(PSTR("\r\nUnknown Device Connected - VID: "), 0x80); + D_PrintHex (VID, 0x80); + Notify(PSTR(" PID: "), 0x80); + D_PrintHex (PID, 0x80); + } + + void NotifyFail(uint8_t rcode) { + D_PrintHex (rcode, 0x80); + Notify(PSTR("\r\n"), 0x80); + } -void NotifyFail(uint8_t rcode) { - D_PrintHex (rcode, 0x80); - Notify(PSTR("\r\n"), 0x80); -} #endif // DEBUG_USB_HOST #endif // USB_FLASH_DRIVE_SUPPORT diff --git a/Marlin/src/sd/usb_flashdrive/lib/message.h b/Marlin/src/sd/usb_flashdrive/lib/message.h index 0cfac6f39..087a4bf50 100644 --- a/Marlin/src/sd/usb_flashdrive/lib/message.h +++ b/Marlin/src/sd/usb_flashdrive/lib/message.h @@ -22,10 +22,11 @@ * Web : http://www.circuitsathome.com * e-mail : support@circuitsathome.com */ -#if !defined(_usb_h_) || defined(__MESSAGE_H__) -#error "Never include message.h directly; include Usb.h instead" -#else -#define __MESSAGE_H__ +#pragma once + +#ifndef _usb_h_ + #error "Never include message.h directly; include Usb.h instead" +#endif extern int UsbDEBUGlvl; @@ -35,52 +36,50 @@ void E_NotifyStr(char const * msg, int lvl); void E_Notifyc(char c, int lvl); #ifdef DEBUG_USB_HOST -#define Notify E_Notify -#define NotifyStr E_NotifyStr -#define Notifyc E_Notifyc -void NotifyFailGetDevDescr(uint8_t reason); -void NotifyFailSetDevTblEntry(uint8_t reason); -void NotifyFailGetConfDescr(uint8_t reason); -void NotifyFailSetConfDescr(uint8_t reason); -void NotifyFailGetDevDescr(void); -void NotifyFailSetDevTblEntry(void); -void NotifyFailGetConfDescr(void); -void NotifyFailSetConfDescr(void); -void NotifyFailUnknownDevice(uint16_t VID, uint16_t PID); -void NotifyFail(uint8_t rcode); + #define Notify E_Notify + #define NotifyStr E_NotifyStr + #define Notifyc E_Notifyc + void NotifyFailGetDevDescr(uint8_t reason); + void NotifyFailSetDevTblEntry(uint8_t reason); + void NotifyFailGetConfDescr(uint8_t reason); + void NotifyFailSetConfDescr(uint8_t reason); + void NotifyFailGetDevDescr(void); + void NotifyFailSetDevTblEntry(void); + void NotifyFailGetConfDescr(void); + void NotifyFailSetConfDescr(void); + void NotifyFailUnknownDevice(uint16_t VID, uint16_t PID); + void NotifyFail(uint8_t rcode); #else -#define Notify(...) ((void)0) -#define NotifyStr(...) ((void)0) -#define Notifyc(...) ((void)0) -#define NotifyFailGetDevDescr(...) ((void)0) -#define NotifyFailSetDevTblEntry(...) ((void)0) -#define NotifyFailGetConfDescr(...) ((void)0) -#define NotifyFailGetDevDescr(...) ((void)0) -#define NotifyFailSetDevTblEntry(...) ((void)0) -#define NotifyFailGetConfDescr(...) ((void)0) -#define NotifyFailSetConfDescr(...) ((void)0) -#define NotifyFailUnknownDevice(...) ((void)0) -#define NotifyFail(...) ((void)0) + #define Notify(...) ((void)0) + #define NotifyStr(...) ((void)0) + #define Notifyc(...) ((void)0) + #define NotifyFailGetDevDescr(...) ((void)0) + #define NotifyFailSetDevTblEntry(...) ((void)0) + #define NotifyFailGetConfDescr(...) ((void)0) + #define NotifyFailGetDevDescr(...) ((void)0) + #define NotifyFailSetDevTblEntry(...) ((void)0) + #define NotifyFailGetConfDescr(...) ((void)0) + #define NotifyFailSetConfDescr(...) ((void)0) + #define NotifyFailUnknownDevice(...) ((void)0) + #define NotifyFail(...) ((void)0) #endif template void ErrorMessage(uint8_t level, char const * msg, ERROR_TYPE rcode = 0) { -#ifdef DEBUG_USB_HOST - Notify(msg, level); - Notify(PSTR(": "), level); - D_PrintHex (rcode, level); - Notify(PSTR("\r\n"), level); -#endif + #ifdef DEBUG_USB_HOST + Notify(msg, level); + Notify(PSTR(": "), level); + D_PrintHex (rcode, level); + Notify(PSTR("\r\n"), level); + #endif } template void ErrorMessage(char const * msg __attribute__((unused)), ERROR_TYPE rcode __attribute__((unused)) = 0) { -#ifdef DEBUG_USB_HOST - Notify(msg, 0x80); - Notify(PSTR(": "), 0x80); - D_PrintHex (rcode, 0x80); - Notify(PSTR("\r\n"), 0x80); -#endif + #ifdef DEBUG_USB_HOST + Notify(msg, 0x80); + Notify(PSTR(": "), 0x80); + D_PrintHex (rcode, 0x80); + Notify(PSTR("\r\n"), 0x80); + #endif } - -#endif // __MESSAGE_H__ diff --git a/Marlin/src/sd/usb_flashdrive/lib/parsetools.cpp b/Marlin/src/sd/usb_flashdrive/lib/parsetools.cpp index 9ed3e94b2..c03ce55cb 100644 --- a/Marlin/src/sd/usb_flashdrive/lib/parsetools.cpp +++ b/Marlin/src/sd/usb_flashdrive/lib/parsetools.cpp @@ -30,53 +30,48 @@ #include "Usb.h" bool MultiByteValueParser::Parse(uint8_t **pp, uint16_t *pcntdn) { - if(!pBuf) { - Notify(PSTR("Buffer pointer is NULL!\r\n"), 0x80); - return false; - } - for(; countDown && (*pcntdn); countDown--, (*pcntdn)--, (*pp)++) - pBuf[valueSize - countDown] = (**pp); + if (!pBuf) { + Notify(PSTR("Buffer pointer is NULL!\r\n"), 0x80); + return false; + } + for (; countDown && (*pcntdn); countDown--, (*pcntdn)--, (*pp)++) + pBuf[valueSize - countDown] = (**pp); - if(countDown) - return false; + if (countDown) return false; - countDown = valueSize; - return true; + countDown = valueSize; + return true; } bool PTPListParser::Parse(uint8_t **pp, uint16_t *pcntdn, PTP_ARRAY_EL_FUNC pf, const void *me) { - switch(nStage) { - case 0: - pBuf->valueSize = lenSize; - theParser.Initialize(pBuf); - nStage = 1; + switch (nStage) { + case 0: + pBuf->valueSize = lenSize; + theParser.Initialize(pBuf); + nStage = 1; - case 1: - if(!theParser.Parse(pp, pcntdn)) - return false; + case 1: + if (!theParser.Parse(pp, pcntdn)) return false; - arLen = 0; - arLen = (pBuf->valueSize >= 4) ? *((uint32_t*)pBuf->pValue) : (uint32_t)(*((uint16_t*)pBuf->pValue)); - arLenCntdn = arLen; - nStage = 2; + arLen = 0; + arLen = (pBuf->valueSize >= 4) ? *((uint32_t*)pBuf->pValue) : (uint32_t)(*((uint16_t*)pBuf->pValue)); + arLenCntdn = arLen; + nStage = 2; - case 2: - pBuf->valueSize = valSize; - theParser.Initialize(pBuf); - nStage = 3; + case 2: + pBuf->valueSize = valSize; + theParser.Initialize(pBuf); + nStage = 3; - case 3: - for(; arLenCntdn; arLenCntdn--) { - if(!theParser.Parse(pp, pcntdn)) - return false; + case 3: + for (; arLenCntdn; arLenCntdn--) { + if (!theParser.Parse(pp, pcntdn)) return false; + if (pf) pf(pBuf, (arLen - arLenCntdn), me); + } - if(pf) - pf(pBuf, (arLen - arLenCntdn), me); - } - - nStage = 0; - } - return true; + nStage = 0; + } + return true; } #endif // USB_FLASH_DRIVE_SUPPORT diff --git a/Marlin/src/sd/usb_flashdrive/lib/parsetools.h b/Marlin/src/sd/usb_flashdrive/lib/parsetools.h index 7b2b91ba1..b075c0539 100644 --- a/Marlin/src/sd/usb_flashdrive/lib/parsetools.h +++ b/Marlin/src/sd/usb_flashdrive/lib/parsetools.h @@ -22,67 +22,65 @@ * Web : http://www.circuitsathome.com * e-mail : support@circuitsathome.com */ +#pragma once -#if !defined(_usb_h_) || defined(__PARSETOOLS_H__) -#error "Never include parsetools.h directly; include Usb.h instead" -#else -#define __PARSETOOLS_H__ +#ifndef _usb_h_ + #error "Never include parsetools.h directly; include Usb.h instead" +#endif struct MultiValueBuffer { - uint8_t valueSize; - void *pValue; + uint8_t valueSize; + void *pValue; } __attribute__((packed)); class MultiByteValueParser { - uint8_t * pBuf; - uint8_t countDown; - uint8_t valueSize; + uint8_t * pBuf; + uint8_t countDown; + uint8_t valueSize; public: - MultiByteValueParser() : pBuf(NULL), countDown(0), valueSize(0) { - }; + MultiByteValueParser() : pBuf(NULL), countDown(0), valueSize(0) { + }; - const uint8_t* GetBuffer() { - return pBuf; - }; + const uint8_t* GetBuffer() { return pBuf; } - void Initialize(MultiValueBuffer * const pbuf) { - pBuf = (uint8_t*)pbuf->pValue; - countDown = valueSize = pbuf->valueSize; - }; + void Initialize(MultiValueBuffer * const pbuf) { + pBuf = (uint8_t*)pbuf->pValue; + countDown = valueSize = pbuf->valueSize; + } - bool Parse(uint8_t **pp, uint16_t *pcntdn); + bool Parse(uint8_t **pp, uint16_t *pcntdn); }; class ByteSkipper { - uint8_t *pBuf; - uint8_t nStage; - uint16_t countDown; + uint8_t *pBuf; + uint8_t nStage; + uint16_t countDown; public: - ByteSkipper() : pBuf(NULL), nStage(0), countDown(0) { - }; - - void Initialize(MultiValueBuffer *pbuf) { - pBuf = (uint8_t*)pbuf->pValue; - countDown = 0; - }; - - bool Skip(uint8_t **pp, uint16_t *pcntdn, uint16_t bytes_to_skip) { - switch(nStage) { - case 0: - countDown = bytes_to_skip; - nStage++; - case 1: - for(; countDown && (*pcntdn); countDown--, (*pp)++, (*pcntdn)--); - - if(!countDown) - nStage = 0; - }; - return (!countDown); - }; + ByteSkipper() : pBuf(NULL), nStage(0), countDown(0) { + } + + void Initialize(MultiValueBuffer *pbuf) { + pBuf = (uint8_t*)pbuf->pValue; + countDown = 0; + } + + bool Skip(uint8_t **pp, uint16_t *pcntdn, uint16_t bytes_to_skip) { + switch (nStage) { + case 0: + countDown = bytes_to_skip; + nStage++; + case 1: + for (; countDown && (*pcntdn); countDown--, (*pp)++, (*pcntdn)--); + + if (!countDown) + nStage = 0; + } + return (!countDown); + } }; // Pointer to a callback function triggered for each element of PTP array when used with PTPArrayParser @@ -91,58 +89,57 @@ typedef void (*PTP_ARRAY_EL_FUNC)(const MultiValueBuffer * const p, uint32_t cou class PTPListParser { public: - enum ParseMode { - modeArray, modeRange/*, modeEnum*/ - }; + enum ParseMode { + modeArray, modeRange/*, modeEnum*/ + }; private: - uint8_t nStage; - uint8_t enStage; + uint8_t nStage; + uint8_t enStage; - uint32_t arLen; - uint32_t arLenCntdn; + uint32_t arLen; + uint32_t arLenCntdn; - uint8_t lenSize; // size of the array length field in bytes - uint8_t valSize; // size of the array element in bytes + uint8_t lenSize; // size of the array length field in bytes + uint8_t valSize; // size of the array element in bytes - MultiValueBuffer *pBuf; + MultiValueBuffer *pBuf; - // The only parser for both size and array element parsing - MultiByteValueParser theParser; + // The only parser for both size and array element parsing + MultiByteValueParser theParser; - uint8_t /*ParseMode*/ prsMode; + uint8_t /*ParseMode*/ prsMode; public: - PTPListParser() : - nStage(0), - enStage(0), - arLen(0), - arLenCntdn(0), - lenSize(0), - valSize(0), - pBuf(NULL), - prsMode(modeArray) { - }; - - void Initialize(const uint8_t len_size, const uint8_t val_size, MultiValueBuffer * const p, const uint8_t mode = modeArray) { - pBuf = p; - lenSize = len_size; - valSize = val_size; - prsMode = mode; - - if(prsMode == modeRange) { - arLenCntdn = arLen = 3; - nStage = 2; - } else { - arLenCntdn = arLen = 0; - nStage = 0; - } - enStage = 0; - theParser.Initialize(p); - }; - - bool Parse(uint8_t **pp, uint16_t *pcntdn, PTP_ARRAY_EL_FUNC pf, const void *me = NULL); + PTPListParser() : + nStage(0), + enStage(0), + arLen(0), + arLenCntdn(0), + lenSize(0), + valSize(0), + pBuf(NULL), + prsMode(modeArray) { } + ; + + void Initialize(const uint8_t len_size, const uint8_t val_size, MultiValueBuffer * const p, const uint8_t mode = modeArray) { + pBuf = p; + lenSize = len_size; + valSize = val_size; + prsMode = mode; + + if (prsMode == modeRange) { + arLenCntdn = arLen = 3; + nStage = 2; + } + else { + arLenCntdn = arLen = 0; + nStage = 0; + } + enStage = 0; + theParser.Initialize(p); + } + + bool Parse(uint8_t **pp, uint16_t *pcntdn, PTP_ARRAY_EL_FUNC pf, const void *me = NULL); }; - -#endif // __PARSETOOLS_H__ diff --git a/Marlin/src/sd/usb_flashdrive/lib/printhex.h b/Marlin/src/sd/usb_flashdrive/lib/printhex.h index aaac3c8f2..2cde3fc34 100644 --- a/Marlin/src/sd/usb_flashdrive/lib/printhex.h +++ b/Marlin/src/sd/usb_flashdrive/lib/printhex.h @@ -22,71 +22,59 @@ * Web : http://www.circuitsathome.com * e-mail : support@circuitsathome.com */ +#pragma once -#if !defined(_usb_h_) || defined(__PRINTHEX_H__) -#error "Never include printhex.h directly; include Usb.h instead" -#else -#define __PRINTHEX_H__ +#ifndef _usb_h_ + #error "Never include printhex.h directly; include Usb.h instead" +#endif void E_Notifyc(char c, int lvl); template void PrintHex(T val, int lvl) { - int num_nibbles = sizeof (T) * 2; - - do { - char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f); - if(v > 57) v += 7; - E_Notifyc(v, lvl); - } while(--num_nibbles); + int num_nibbles = sizeof (T) * 2; + do { + char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f); + if (v > 57) v += 7; + E_Notifyc(v, lvl); + } while (--num_nibbles); } template void PrintBin(T val, int lvl) { - for(T mask = (((T)1) << ((sizeof (T) << 3) - 1)); mask; mask >>= 1) - if(val & mask) - E_Notifyc('1', lvl); - else - E_Notifyc('0', lvl); + for (T mask = (((T)1) << ((sizeof (T) << 3) - 1)); mask; mask >>= 1) + E_Notifyc(val & mask ? '1' : '0', lvl); } template void SerialPrintHex(T val) { - int num_nibbles = sizeof (T) * 2; - - do { - char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f); - if(v > 57) v += 7; - USB_HOST_SERIAL.print(v); - } while(--num_nibbles); + int num_nibbles = sizeof (T) * 2; + do { + char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f); + if (v > 57) v += 7; + USB_HOST_SERIAL.print(v); + } while (--num_nibbles); } template void PrintHex2(Print *prn, T val) { - T mask = (((T)1) << (((sizeof (T) << 1) - 1) << 2)); - - while(mask > 1) { - if(val < mask) - prn->print("0"); - - mask >>= 4; - } - prn->print((T)val, HEX); + T mask = (((T)1) << (((sizeof (T) << 1) - 1) << 2)); + while (mask > 1) { + if (val < mask) prn->print("0"); + mask >>= 4; + } + prn->print((T)val, HEX); } template void D_PrintHex(T val __attribute__((unused)), int lvl __attribute__((unused))) { -#ifdef DEBUG_USB_HOST - PrintHex (val, lvl); -#endif + #ifdef DEBUG_USB_HOST + PrintHex (val, lvl); + #endif } template void D_PrintBin(T val, int lvl) { -#ifdef DEBUG_USB_HOST - PrintBin (val, lvl); -#endif + #ifdef DEBUG_USB_HOST + PrintBin (val, lvl); + #endif } - - - -#endif // __PRINTHEX_H__ diff --git a/Marlin/src/sd/usb_flashdrive/lib/settings.h b/Marlin/src/sd/usb_flashdrive/lib/settings.h index 066c45daa..dc7782f2a 100644 --- a/Marlin/src/sd/usb_flashdrive/lib/settings.h +++ b/Marlin/src/sd/usb_flashdrive/lib/settings.h @@ -35,7 +35,7 @@ * flash drives and simple USB hard drives. * Disable this by defining DELAY(x) to be delay(x). */ - #define delay(x) if((x) < 200) safe_delay(x) + #define delay(x) if ((x) < 200) safe_delay(x) /* Almost all USB flash drives and simple USB hard drives fail the write * protect test and add 20 - 30 seconds to USB init. Set SKIP_WRITE_PROTECT * to nonzero to skip the test and assume the drive is writable. diff --git a/Marlin/src/sd/usb_flashdrive/lib/usb_ch9.h b/Marlin/src/sd/usb_flashdrive/lib/usb_ch9.h index 00794ee78..039215b1b 100644 --- a/Marlin/src/sd/usb_flashdrive/lib/usb_ch9.h +++ b/Marlin/src/sd/usb_flashdrive/lib/usb_ch9.h @@ -23,12 +23,11 @@ * e-mail : support@circuitsathome.com */ -#if !defined(_usb_h_) || defined(_ch9_h_) -#error "Never include usb_ch9.h directly; include Usb.h instead" -#else +#ifndef _usb_h_ + #error "Never include usb_ch9.h directly; include Usb.h instead" +#endif /* USB chapter 9 structures */ -#define _ch9_h_ /* Misc.USB constants */ #define DEV_DESCR_LEN 18 //device descriptor length @@ -81,7 +80,6 @@ #define HID_DESCRIPTOR_HID 0x21 - /* OTG SET FEATURE Constants */ #define OTG_FEATURE_B_HNP_ENABLE 3 // SET FEATURE OTG - Enable B device to perform HNP #define OTG_FEATURE_A_HNP_SUPPORT 4 // SET FEATURE OTG - A device supports HNP @@ -170,5 +168,3 @@ typedef struct { uint8_t bDescrType; // Type of class descriptor uint16_t wDescriptorLength; // Total size of the Report descriptor } __attribute__((packed)) HID_CLASS_DESCRIPTOR_LEN_AND_TYPE; - -#endif // _ch9_h_