Coding standards

This commit is contained in:
Scott Lahteine 2019-02-12 16:25:49 -06:00
parent 19af90face
commit 3a1b6fe8c1
43 changed files with 2033 additions and 2344 deletions

View File

@ -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) {

View File

@ -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;

View File

@ -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" {

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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];

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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;
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;
/* 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);

View File

@ -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;
else {
uint32_t offaddress = state->regData[rn].v + (U ? imm8 + imm8 : 0),
address = P ? offaddress : state->regData[rn].v;
uint32_t address;
if (P) {
address = offaddress;
} else {
address = 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 */
}
else /* Propagate unknown value */
state->regData[rt].o = state->regData[rn].o;
}
} else {
}
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;
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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) {

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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))

File diff suppressed because it is too large Load Diff

View File

@ -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_

View File

@ -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;
}

View File

@ -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
uint8_t epAddr; // Endpoint address
uint8_t maxPktSize; // Maximum packet size
union {
uint8_t epAttribs;
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));
};
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 <const uint8_t MAX_DEVICES_ALLOWED>
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];
// Initializes address pool entry
// Initialize 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;
}
// Returns thePool index for a given address
// Return 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;
}
return 0;
};
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;
// Returns thePool child index for a given parent
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;
};
// Return thePool child index for a given parent
// Frees address entry specified by index parameter
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;
}
void FreeAddressByIndex(uint8_t index) {
// Zero field is reserved and should not be affected
if(index == 0)
return;
// Frees address entry specified by index parameter
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);
void FreeAddressByIndex(uint8_t index) {
// Zero field is reserved and should not be affected
if (index == 0) return;
// If the hub had the last allocated address, hubCounter should be decremented
if(hubCounter == uda.bmAddress)
hubCounter--;
}
InitEntry(index);
}
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);
// Initializes the whole address pool at once
// If the hub had the last allocated address, hubCounter should be decremented
if (hubCounter == uda.bmAddress) hubCounter--;
}
InitEntry(index);
}
void InitAllAddresses() {
for(uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++)
InitEntry(i);
// Initialize the whole address pool at once
hubCounter = 0;
};
void InitAllAddresses() {
for (uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++)
InitEntry(i);
hubCounter = 0;
}
public:
AddressPoolImpl() : hubCounter(0) {
// Zero address is reserved
InitEntry(0);
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;
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();
};
InitAllAddresses();
}
// Returns a pointer to a specified address entry
// Return a pointer to a specified address entry
virtual UsbDevice* GetUsbDevicePtr(uint8_t addr) {
if(!addr)
return thePool;
virtual UsbDevice* GetUsbDevicePtr(uint8_t addr) {
if (!addr) return thePool;
uint8_t index = FindAddressIndex(addr);
return index ? thePool + index : NULL;
}
uint8_t index = FindAddressIndex(addr);
// Perform an operation specified by pfunc for each addressed device
return (!index) ? NULL : thePool + index;
};
void ForEachUsbDevice(UsbDeviceHandleFunc pfunc) {
if (pfunc) {
for (uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++)
if (thePool[i].address.devAddress)
pfunc(thePool + i);
}
}
// Performs an operation specified by pfunc for each addressed device
// Allocate new address
void ForEachUsbDevice(UsbDeviceHandleFunc pfunc) {
if(!pfunc)
return;
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;
for(uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++)
if(thePool[i].address.devAddress)
pfunc(thePool + i);
};
if (is_hub && hubCounter == 7) return 0;
// Allocates new address
// finds first empty address entry starting from one
uint8_t index = FindAddressIndex(0);
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 (!index) return 0; // if empty entry is not found
if(is_hub && hubCounter == 7)
return 0;
if (_parent.devAddress == 0) {
if (is_hub) {
thePool[index].address.devAddress = 0x41;
hubCounter++;
}
else
thePool[index].address.devAddress = 1;
// finds first empty address entry starting from one
uint8_t index = FindAddressIndex(0);
return thePool[index].address.devAddress;
}
if(!index) // if empty entry is not found
return 0;
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;
}
if(_parent.devAddress == 0) {
if(is_hub) {
thePool[index].address.devAddress = 0x41;
hubCounter++;
} else
thePool[index].address.devAddress = 1;
// Empty the pool entry
return thePool[index].address.devAddress;
}
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));
}
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<MAX_DEVICES_ALLOWED; i++)
// if (thePool[i].address != 0);
// counter ++;
// return counter;
//};
// 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__

View File

@ -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 <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
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 <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::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 <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
void ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::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 <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor(uint8_t **pp, uint16_t *pcntdn) {
USB_CONFIGURATION_DESCRIPTOR* ucd = reinterpret_cast<USB_CONFIGURATION_DESCRIPTOR*>(varBuffer);
USB_INTERFACE_DESCRIPTOR* uid = reinterpret_cast<USB_INTERFACE_DESCRIPTOR*>(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<USB_CONFIGURATION_DESCRIPTOR*>(varBuffer);
USB_INTERFACE_DESCRIPTOR* uid = reinterpret_cast<USB_INTERFACE_DESCRIPTOR*>(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 <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
void ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc) {
Notify(PSTR("\r\n\r\nHID Descriptor:\r\n"), 0x80);
Notify(PSTR("bDescLength:\t\t"), 0x80);
PrintHex<uint8_t > (pDesc->bLength, 0x80);
Notify(PSTR("\r\n\r\nHID Descriptor:\r\n"), 0x80);
Notify(PSTR("bDescLength:\t\t"), 0x80);
PrintHex<uint8_t > (pDesc->bLength, 0x80);
Notify(PSTR("\r\nbDescriptorType:\t"), 0x80);
PrintHex<uint8_t > (pDesc->bDescriptorType, 0x80);
Notify(PSTR("\r\nbDescriptorType:\t"), 0x80);
PrintHex<uint8_t > (pDesc->bDescriptorType, 0x80);
Notify(PSTR("\r\nbcdHID:\t\t\t"), 0x80);
PrintHex<uint16_t > (pDesc->bcdHID, 0x80);
Notify(PSTR("\r\nbcdHID:\t\t\t"), 0x80);
PrintHex<uint16_t > (pDesc->bcdHID, 0x80);
Notify(PSTR("\r\nbCountryCode:\t\t"), 0x80);
PrintHex<uint8_t > (pDesc->bCountryCode, 0x80);
Notify(PSTR("\r\nbCountryCode:\t\t"), 0x80);
PrintHex<uint8_t > (pDesc->bCountryCode, 0x80);
Notify(PSTR("\r\nbNumDescriptors:\t"), 0x80);
PrintHex<uint8_t > (pDesc->bNumDescriptors, 0x80);
Notify(PSTR("\r\nbNumDescriptors:\t"), 0x80);
PrintHex<uint8_t > (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<uint8_t > (pLT[i].bDescrType, 0x80);
Notify(PSTR("\r\nbDescrType:\t\t"), 0x80);
PrintHex<uint8_t > (pLT[i].bDescrType, 0x80);
Notify(PSTR("\r\nwDescriptorLength:\t"), 0x80);
PrintHex<uint16_t > (pLT[i].wDescriptorLength, 0x80);
}
Notify(PSTR("\r\n"), 0x80);
Notify(PSTR("\r\nwDescriptorLength:\t"), 0x80);
PrintHex<uint16_t > (pLT[i].wDescriptorLength, 0x80);
}
Notify(PSTR("\r\n"), 0x80);
}
#endif // __CONFDESCPARSER_H__

View File

@ -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 BASE_CLASS, class LEN_TYPE, class OFFSET_TYPE>
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 <class BASE_CLASS, class LEN_TYPE, class OFFSET_TYPE>
void HexDumper<BASE_CLASS, LEN_TYPE, OFFSET_TYPE>::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<OFFSET_TYPE > (byteTotal, 0x80);
E_Notify(PSTR(": "), 0x80);
}
PrintHex<uint8_t > (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<OFFSET_TYPE > (byteTotal, 0x80);
E_Notify(PSTR(": "), 0x80);
}
PrintHex<uint8_t > (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__

View File

@ -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__

File diff suppressed because it is too large Load Diff

View File

@ -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);
};

View File

@ -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_

View File

@ -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<uint16_t > (VID, 0x80);
Notify(PSTR(" PID: "), 0x80);
D_PrintHex<uint16_t > (PID, 0x80);
}
void NotifyFailUnknownDevice(uint16_t VID, uint16_t PID) {
Notify(PSTR("\r\nUnknown Device Connected - VID: "), 0x80);
D_PrintHex<uint16_t > (VID, 0x80);
Notify(PSTR(" PID: "), 0x80);
D_PrintHex<uint16_t > (PID, 0x80);
}
void NotifyFail(uint8_t rcode) {
D_PrintHex<uint8_t > (rcode, 0x80);
Notify(PSTR("\r\n"), 0x80);
}
void NotifyFail(uint8_t rcode) {
D_PrintHex<uint8_t > (rcode, 0x80);
Notify(PSTR("\r\n"), 0x80);
}
#endif // DEBUG_USB_HOST
#endif // USB_FLASH_DRIVE_SUPPORT

View File

@ -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 <class ERROR_TYPE>
void ErrorMessage(uint8_t level, char const * msg, ERROR_TYPE rcode = 0) {
#ifdef DEBUG_USB_HOST
Notify(msg, level);
Notify(PSTR(": "), level);
D_PrintHex<ERROR_TYPE > (rcode, level);
Notify(PSTR("\r\n"), level);
#endif
#ifdef DEBUG_USB_HOST
Notify(msg, level);
Notify(PSTR(": "), level);
D_PrintHex<ERROR_TYPE > (rcode, level);
Notify(PSTR("\r\n"), level);
#endif
}
template <class ERROR_TYPE>
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<ERROR_TYPE > (rcode, 0x80);
Notify(PSTR("\r\n"), 0x80);
#endif
#ifdef DEBUG_USB_HOST
Notify(msg, 0x80);
Notify(PSTR(": "), 0x80);
D_PrintHex<ERROR_TYPE > (rcode, 0x80);
Notify(PSTR("\r\n"), 0x80);
#endif
}
#endif // __MESSAGE_H__

View File

@ -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

View File

@ -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) {
};
ByteSkipper() : pBuf(NULL), nStage(0), countDown(0) {
}
void Initialize(MultiValueBuffer *pbuf) {
pBuf = (uint8_t*)pbuf->pValue;
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)--);
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);
};
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) {
};
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;
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);
};
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);
bool Parse(uint8_t **pp, uint16_t *pcntdn, PTP_ARRAY_EL_FUNC pf, const void *me = NULL);
};
#endif // __PARSETOOLS_H__

View File

@ -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 <class T>
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 <class T>
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 <class T>
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 <class T>
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 <class T> void D_PrintHex(T val __attribute__((unused)), int lvl __attribute__((unused))) {
#ifdef DEBUG_USB_HOST
PrintHex<T > (val, lvl);
#endif
#ifdef DEBUG_USB_HOST
PrintHex<T > (val, lvl);
#endif
}
template <class T>
void D_PrintBin(T val, int lvl) {
#ifdef DEBUG_USB_HOST
PrintBin<T > (val, lvl);
#endif
#ifdef DEBUG_USB_HOST
PrintBin<T > (val, lvl);
#endif
}
#endif // __PRINTHEX_H__

View File

@ -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.

View File

@ -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_