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

@ -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,7 +45,6 @@
#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);
@ -77,8 +76,7 @@ void pinMode_LCD(uint8_t pin, uint8_t mode) {
config.Pinmode = PINSEL_PINMODE_PULLUP;
PINSEL_ConfigPin(&config);
break;
default:
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,8 +95,7 @@ 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_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;
}

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

@ -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
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 */
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);
@ -143,10 +125,11 @@ UnwResult UnwStartArm(UnwState * const state) {
/* MRS */
else if ((instr & 0xFFBF0FFF) == 0xE10F0000) {
#ifdef UNW_DEBUG
bool R = (instr & 0x00400000) ? true : false;
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 */
@ -155,10 +138,9 @@ UnwResult UnwStartArm(UnwState * const state) {
/* MSR */
else if ((instr & 0xFFB0F000) == 0xE120F000) {
#ifdef UNW_DEBUG
bool R = (instr & 0x00400000) ? true : false;
UnwPrintd2("MSR %s_?, ???", R ? "SPSR" : "CPSR");
UnwPrintd2("MSR %s_?, ???", (instr & 0x00400000) ? "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,10 +152,10 @@ 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;
bool S = !!(instr & 0x00100000);
#endif
uint8_t rn = (instr & 0x000F0000) >> 16;
uint8_t rd = (instr & 0x0000F000) >> 12;
@ -217,7 +199,7 @@ 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
@ -227,16 +209,13 @@ UnwResult UnwStartArm(UnwState * const state) {
/* 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,10 +229,7 @@ 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));
}
@ -264,32 +240,22 @@ UnwResult UnwStartArm(UnwState * const state) {
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) | (0xFFFFFFFF << (32 - shiftDist));
}
else {
else
op2val = state->regData[rm].v >> shiftDist;
op2val |= 0xFFFFFFFF << (32 - shiftDist);
}
}
else {
op2val = state->regData[rm].v >> shiftDist;
}
break;
case 3: /* rotate right */
@ -317,16 +283,11 @@ 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) {
@ -374,10 +335,7 @@ 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 */
@ -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,11 +396,11 @@ 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;
@ -455,13 +409,12 @@ UnwResult UnwStartArm(UnwState * const state) {
#ifdef UNW_DEBUG
/* Display the instruction */
if (L) {
if (L)
UnwPrintd6("LDM%c%c r%d%s, {reglist}%s\n", P ? 'E' : 'F', U ? 'D' : 'A', baseReg, W ? "!" : "", S ? "^" : "");
}
else {
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])) {
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,9 +39,8 @@ 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);
@ -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,7 +76,7 @@ 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) {
@ -98,9 +90,8 @@ UnwResult UnwStartThumb(UnwState * const state) {
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)) {
@ -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);
@ -161,13 +151,12 @@ 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;
}
}
}
}
}
/*
* PUSH register
*/
@ -180,10 +169,9 @@ 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,9 +182,8 @@ 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)) {
@ -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 {
uint8_t rv;
if(!state->cb->readB((state->regData[15].v & (~1)) + 2, &rv)) {
return UNWIND_DREAD_B_FAIL;
}
else {
uint8_t rv;
if (!state->cb->readB((state->regData[15].v & (~1)) + 2, &rv))
return UNWIND_DREAD_B_FAIL;
state->regData[15].v += rv * 2;
}
}
@ -355,9 +340,8 @@ 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) {
@ -414,7 +398,7 @@ UnwResult UnwStartThumb(UnwState * const state) {
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,10 +408,9 @@ 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.
* We are only interested when destination is PC.
@ -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 {
uint32_t address = state->regData[rn].v + imm12;
if(!UnwMemReadRegister(state, address, &state->regData[rt])) {
return UNWIND_DREAD_W_FAIL;
}
else {
uint32_t address = state->regData[rn].v + imm12;
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,32 +465,30 @@ 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 {
UnwPrintd1("???? (32)");
@ -535,10 +505,10 @@ UnwResult UnwStartThumb(UnwState * const state) {
*/
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) {
case 0: /* LSL */
@ -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;
@ -575,8 +543,8 @@ UnwResult UnwStartThumb(UnwState * const state) {
* SUB Rd, Rs, #Offset3
*/
else if ((instr & 0xF800) == 0x1800) {
bool I = (instr & 0x0400) ? true : false;
bool op = (instr & 0x0200) ? true : false;
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);
@ -589,31 +557,19 @@ UnwResult UnwStartThumb(UnwState * const state) {
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;
@ -796,9 +752,8 @@ UnwResult UnwStartThumb(UnwState * const state) {
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 */
@ -833,10 +788,8 @@ 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) {
case 0: /* ADD */
@ -865,9 +818,8 @@ UnwResult UnwStartThumb(UnwState * const state) {
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;
@ -879,11 +831,9 @@ UnwResult UnwStartThumb(UnwState * const state) {
/* 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));
return UNWIND_FAILURE;
@ -903,10 +853,9 @@ 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
@ -931,8 +880,8 @@ UnwResult UnwStartThumb(UnwState * const state) {
* POP {Rlist, PC}
*/
else if ((instr & 0xF600) == 0xB400) {
bool L = (instr & 0x0800) ? true : false;
bool R = (instr & 0x0100) ? true : false;
bool L = !!(instr & 0x0800);
bool R = !!(instr & 0x0100);
uint8_t rList = (instr & 0x00FF);
if (L) {
@ -945,14 +894,12 @@ UnwResult UnwStartThumb(UnwState * const state) {
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;
@ -963,9 +910,8 @@ UnwResult UnwStartThumb(UnwState * const state) {
/* Check if the PC is to be popped */
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)) {
@ -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);
@ -1014,10 +959,9 @@ UnwResult UnwStartThumb(UnwState * const state) {
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)) {
@ -1025,13 +969,12 @@ 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;
}
}
}
}
}
/*
* Conditional branches
@ -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,9 +1057,7 @@ 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);

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)))
@ -36,9 +36,7 @@ static int16_t memHashIndex(MemData * const memData, const uint32_t addr) {
/* Check if the element is occupied */
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,9 +45,7 @@ static int16_t memHashIndex(MemData * const memData, const uint32_t addr) {
/* Search the next entry */
s++;
if(s > MEM_HASH_SIZE) {
s = 0;
}
if (s > MEM_HASH_SIZE) s = 0;
} while (s != v);
/* Search failed, hash is full and the address not stored */
@ -58,7 +54,7 @@ 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) {
*data = memData->v[i];
@ -72,20 +68,14 @@ 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);
if(i < 0){
/* Hash full */
return false;
}
else {
/* Store the item */
memData->a[i] = addr;
M_SetIdxUsed(memData->used, i);
if(valValid)
{
if (valValid) {
memData->v[i] = val;
M_SetIdxUsed(memData->tracked, i);
}
@ -98,7 +88,6 @@ bool UnwMemHashWrite(MemData * const memData, uint32_t addr, uint32_t val, bool
return true;
}
}
void UnwMemHashGC(UnwState * const state) {
@ -109,7 +98,6 @@ void UnwMemHashGC(UnwState * const state) {
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

@ -145,9 +145,7 @@ uint8_t USB::ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bReque
uint16_t nak_limit = 0;
rcode = SetAddress(addr, ep, &pep, &nak_limit);
if(rcode)
return rcode;
if (rcode) return rcode;
direction = ((bmReqType & 0x80) > 0);
@ -162,16 +160,11 @@ uint8_t USB::ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bReque
bytesWr(rSUDFIFO, 8, (uint8_t*) & setup_pkt); //transfer to setup packet FIFO
rcode = dispatchPkt(tokSETUP, ep, nak_limit); //dispatch packet
if (rcode) return rcode; // Return HRSLT if not zero
if(rcode) //return HRSLT if not zero
return ( rcode);
if(dataptr != NULL) //data stage, if present
{
if(direction) //IN transfer
{
if (dataptr != NULL) { //data stage, if present
if (direction) { //IN transfer
uint16_t left = total;
pep->bmRcvToggle = 1; //bmRCVTOG1;
while (left) {
@ -186,25 +179,21 @@ uint8_t USB::ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bReque
continue;
}
if(rcode)
return rcode;
if (rcode) return rcode;
// Invoke callback function if inTransfer completed successfully and callback function pointer is specified
if(!rcode && p)
((USBReadParser*)p)->Parse(read, dataptr, total - left);
if (!rcode && p) ((USBReadParser*)p)->Parse(read, dataptr, total - left);
left -= read;
if(read < nbytes)
break;
if (read < nbytes) break;
}
} else //OUT transfer
{
}
else { //OUT transfer
pep->bmSndToggle = 1; //bmSNDTOG1;
rcode = OutTransfer(pep, nak_limit, nbytes, dataptr);
}
if(rcode) //return error
return ( rcode);
if (rcode) return rcode; // return error
}
// Status stage
return dispatchPkt((direction) ? tokOUTHS : tokINHS, ep, nak_limit); //GET if direction
@ -220,7 +209,6 @@ uint8_t USB::inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t*
uint16_t nak_limit = 0;
uint8_t rcode = SetAddress(addr, ep, &pep, &nak_limit);
if (rcode) {
USBTRACE3("(USB::InTransfer) SetAddress Failed ", rcode, 0x81);
USBTRACE3("(USB::InTransfer) addr requested ", addr, 0x81);
@ -242,7 +230,7 @@ uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, ui
regWr(rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0); //set toggle value
// use a 'break' to exit this loop
while(1) {
for (;;) {
rcode = dispatchPkt(tokIN, pep->epAddr, nak_limit); //IN packet to EP-'endpoint'. Function takes care of NAKS.
if (rcode == hrTOGERR) {
// yes, we flip it wrong here so that next time it is actually correct!
@ -258,7 +246,7 @@ uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, ui
/* the only case when absence of RCVDAVIRQ makes sense is when toggle error occurred. Need to add handling for that */
if ((regRd(rHIRQ) & bmRCVDAVIRQ) == 0) {
//printf(">>>>>>>> Problem! NO RCVDAVIRQ!\r\n");
rcode = 0xf0; //receive error
rcode = 0xF0; //receive error
break;
}
pktsize = regRd(rRCVBC); //number of received bytes
@ -273,9 +261,7 @@ uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, ui
}
int16_t mem_left = (int16_t)nbytes - *((int16_t*)nbytesptr);
if(mem_left < 0)
mem_left = 0;
if (mem_left < 0) mem_left = 0;
data = bytesRd(rRCVFIFO, ((pktsize > mem_left) ? mem_left : pktsize), data);
@ -285,17 +271,17 @@ uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, ui
/* The transfer is complete under two conditions: */
/* 1. The device sent a short packet (L.T. maxPacketSize) */
/* 2. 'nbytes' have been transferred. */
if((pktsize < maxpktsize) || (*nbytesptr >= nbytes)) // have we transferred 'nbytes' bytes?
{
if (pktsize < maxpktsize || *nbytesptr >= nbytes) { // Transferred 'nbytes' bytes?
// Save toggle value
pep->bmRcvToggle = ((regRd(rHRSL) & bmRCVTOGRD)) ? 1 : 0;
//printf("\r\n");
rcode = 0;
break;
} else if(bInterval > 0)
}
else if (bInterval > 0)
delay(bInterval); // Delay according to polling interval
} //while( 1 )
return ( rcode);
}
return rcode;
}
/* OUT transfer to arbitrary endpoint. Handles multiple packets if necessary. Transfers 'nbytes' bytes. */
@ -307,9 +293,7 @@ uint8_t USB::outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dat
uint16_t nak_limit = 0;
uint8_t rcode = SetAddress(addr, ep, &pep, &nak_limit);
if(rcode)
return rcode;
if (rcode) return rcode;
return OutTransfer(pep, nak_limit, nbytes, data);
}
@ -338,7 +322,7 @@ uint8_t USB::OutTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8
regWr(rHXFR, (tokOUT | pep->epAddr)); //dispatch packet
while (!(regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ
regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ
rcode = (regRd(rHRSL) & 0x0f);
rcode = (regRd(rHRSL) & 0x0F);
while (rcode && ((int32_t)((uint32_t)millis() - timeout) < 0L)) {
switch (rcode) {
@ -361,7 +345,7 @@ uint8_t USB::OutTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8
break;
default:
goto breakout;
}//switch( rcode
}
/* process NAK according to Host out NAK bug */
regWr(rSNDBC, 0);
@ -370,22 +354,23 @@ uint8_t USB::OutTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8
regWr(rHXFR, (tokOUT | pep->epAddr)); //dispatch packet
while (!(regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ
regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ
rcode = (regRd(rHRSL) & 0x0f);
}//while( rcode && ....
rcode = (regRd(rHRSL) & 0x0F);
} // while rcode && ....
bytes_left -= bytes_tosend;
data_p += bytes_tosend;
}//while( bytes_left...
} // while bytes_left...
breakout:
pep->bmSndToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 1 : 0; //bmSNDTOG1 : bmSNDTOG0; //update toggle
return ( rcode); //should be 0 in all cases
}
/* dispatch USB packet. Assumes peripheral address is set and relevant buffer is loaded/empty */
/* If NAK, tries to re-send up to nak_limit times */
/* If nak_limit == 0, do not count NAKs, exit after timeout */
/* If bus timeout, re-sends up to USB_RETRY_LIMIT times */
/* return codes 0x00-0x0f are HRSLT( 0x00 being success ), 0xff means timeout */
/* return codes 0x00-0x0F are HRSLT( 0x00 being success ), 0xFF means timeout */
uint8_t USB::dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit) {
uint32_t timeout = (uint32_t)millis() + USB_XFER_TIMEOUT;
uint8_t tmpdata;
@ -400,10 +385,9 @@ uint8_t USB::dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit) {
regWr(rHXFR, (token | ep)); //launch the transfer
rcode = USB_ERROR_TRANSFER_TIMEOUT;
while((int32_t)((uint32_t)millis() - timeout) < 0L) //wait for transfer completion
{
while ((int32_t)((uint32_t)millis() - timeout) < 0L) { //wait for transfer completion
#if defined(ESP8266) || defined(ESP32)
yield(); // needed in order to reset the watchdog timer on the ESP8266
yield(); // needed to reset the watchdog timer on the ESP8266
#endif
tmpdata = regRd(rHIRQ);
@ -411,14 +395,14 @@ uint8_t USB::dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit) {
regWr(rHIRQ, bmHXFRDNIRQ); //clear the interrupt
rcode = 0x00;
break;
}//if( tmpdata & bmHXFRDNIRQ
}
}//while ( millis() < timeout
} // while millis() < timeout
//if (rcode != 0x00) //exit if timeout
// return ( rcode);
rcode = (regRd(rHRSL) & 0x0f); //analyze transfer result
rcode = (regRd(rHRSL) & 0x0F); //analyze transfer result
switch (rcode) {
case hrNAK:
@ -433,15 +417,14 @@ uint8_t USB::dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit) {
break;
default:
return (rcode);
}//switch( rcode
}
}//while( timeout > millis()
return ( rcode);
} // while timeout > millis()
return rcode;
}
/* USB main task. Performs enumeration/cleanup */
void USB::Task(void) //USB state machine
{
void USB::Task(void) { //USB state machine
uint8_t rcode;
uint8_t tmpdata;
static uint32_t delay = 0;
@ -464,7 +447,6 @@ void USB::Task(void) //USB state machine
lowspeed = false;
break;
case LSHOST:
lowspeed = true;
//intentional fallthrough
case FSHOST: //attached
@ -473,11 +455,10 @@ void USB::Task(void) //USB state machine
usb_task_state = USB_ATTACHED_SUBSTATE_SETTLE;
}
break;
}// switch( tmpdata
}
for (uint8_t i = 0; i < USB_NUMDEVICES; i++)
if(devConfig[i])
rcode = devConfig[i]->Poll();
if (devConfig[i]) rcode = devConfig[i]->Poll();
switch (usb_task_state) {
case USB_DETACHED_SUBSTATE_INITIALIZE:
@ -530,20 +511,19 @@ void USB::Task(void) //USB state machine
rcode = Configuring(0, 0, lowspeed);
if(rcode) {
if(rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE) {
if (!rcode)
usb_task_state = USB_STATE_RUNNING;
else if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE) {
usb_error = rcode;
usb_task_state = USB_STATE_ERROR;
}
} else
usb_task_state = USB_STATE_RUNNING;
break;
case USB_STATE_RUNNING:
break;
case USB_STATE_ERROR:
//MAX3421E::Init();
break;
} // switch( usb_task_state )
}
}
uint8_t USB::DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed) {
@ -553,38 +533,28 @@ uint8_t USB::DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed) {
// Get pointer to pseudo device with address 0 assigned
p0 = addrPool.GetUsbDevicePtr(0);
if (!p0) return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
if (!p0->epinfo) return USB_ERROR_EPINFO_IS_NULL;
if(!p0)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
if(!p0->epinfo)
return USB_ERROR_EPINFO_IS_NULL;
p0->lowspeed = (lowspeed) ? true : false;
p0->lowspeed = lowspeed;
// Allocate new address according to device class
uint8_t bAddress = addrPool.AllocAddress(parent, false, port);
if(!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
if (!bAddress) return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
p = addrPool.GetUsbDevicePtr(bAddress);
if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
if (!p) return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
p->lowspeed = lowspeed;
// Assign new address to the device
rcode = setAddr(0, 0, bAddress);
if (rcode) {
addrPool.FreeAddress(bAddress);
bAddress = 0;
}
return rcode;
}
return 0;
};
uint8_t USB::AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lowspeed) {
//printf("AttemptConfig: parent = %i, port = %i\r\n", parent, port);
@ -597,15 +567,18 @@ again:
// Send a bus reset on the root interface.
regWr(rHCTL, bmBUSRST); //issue bus reset
delay(102); // delay 102ms, compensate for clock inaccuracy.
} else {
}
else {
// reset parent port
devConfig[parent]->ResetHubPort(port);
}
} else if(rcode == hrJERR && retries < 3) { // Some devices returns this when plugged in - trying to initialize the device again usually works
}
else if (rcode == hrJERR && retries < 3) { // Some devices returns this when plugged in - trying to initialize the device again usually works
delay(100);
retries++;
goto again;
} else if(rcode)
}
else if (rcode)
return rcode;
rcode = devConfig[driver]->Init(parent, port, lowspeed);
@ -614,13 +587,15 @@ again:
retries++;
goto again;
}
if (rcode) {
// Issue a bus reset, because the device may be in a limbo state
if (parent == 0) {
// Send a bus reset on the root interface.
regWr(rHCTL, bmBUSRST); //issue bus reset
delay(102); // delay 102ms, compensate for clock inaccuracy.
} else {
}
else {
// reset parent port
devConfig[parent]->ResetHubPort(port);
}
@ -628,11 +603,10 @@ again:
return rcode;
}
/*
* This is broken. We need to enumerate differently.
/**
* This is broken. It needs to enumerate differently.
* It causes major problems with several devices if detected in an unexpected order.
*
*
* Oleg - I wouldn't do anything before the newly connected device is considered sane.
* i.e.(delays are not indicated for brevity):
* 1. reset
@ -718,10 +692,9 @@ uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) {
// Allocate new address according to device class
//bAddress = addrPool.AllocAddress(parent, false, port);
uint16_t vid = udd->idVendor;
uint16_t pid = udd->idProduct;
uint8_t klass = udd->bDeviceClass;
uint8_t subklass = udd->bDeviceSubClass;
uint16_t vid = udd->idVendor, pid = udd->idProduct;
uint8_t klass = udd->bDeviceClass, subklass = udd->bDeviceSubClass;
// Attempt to configure if VID/PID or device class matches with a driver
// Qualify with subclass too.
//
@ -738,10 +711,7 @@ uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) {
}
}
if(devConfigIndex < USB_NUMDEVICES) {
return rcode;
}
if (devConfigIndex < USB_NUMDEVICES) return rcode;
// blindly attempt to configure
for (devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) {
@ -760,21 +730,18 @@ uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) {
return rcode;
}
}
// if we get here that means that the device class is not supported by any of registered classes
rcode = DefaultAddressing(parent, port, lowspeed);
return rcode;
// Arriving here means the device class is unsupported by registered classes
return DefaultAddressing(parent, port, lowspeed);
}
uint8_t USB::ReleaseDevice(uint8_t addr) {
if(!addr)
return 0;
if (addr) {
for (uint8_t i = 0; i < USB_NUMDEVICES; i++) {
if (!devConfig[i]) continue;
if (devConfig[i]->GetAddress() == addr)
return devConfig[i]->Release();
}
}
return 0;
}
@ -782,12 +749,12 @@ uint8_t USB::ReleaseDevice(uint8_t addr) {
//get device descriptor
uint8_t USB::getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr) {
return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, nbytes, dataptr, NULL));
return ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, nbytes, dataptr, NULL);
}
//get configuration descriptor
uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t* dataptr) {
return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, nbytes, dataptr, NULL));
return ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, nbytes, dataptr, NULL);
}
/* Requests Configuration Descriptor. Sends two Get Conf Descr requests. The first one gets the total length of all descriptors, then the second one requests this
@ -798,21 +765,19 @@ uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint8_t conf, USBReadParser
USB_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast<USB_CONFIGURATION_DESCRIPTOR *>(buf);
uint8_t ret = getConfDescr(addr, ep, 9, conf, buf);
if(ret)
return ret;
if (ret) return ret;
uint16_t total = ucd->wTotalLength;
//USBTRACE2("\r\ntotal conf.size:", total);
return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, total, bufSize, buf, p));
return ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, total, bufSize, buf, p);
}
//get string descriptor
uint8_t USB::getStrDescr(uint8_t addr, uint8_t ep, uint16_t ns, uint8_t index, uint16_t langid, uint8_t* dataptr) {
return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, ns, ns, dataptr, NULL));
return ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, ns, ns, dataptr, NULL);
}
//set address
@ -821,12 +786,12 @@ uint8_t USB::setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr) {
//delay(2); //per USB 2.0 sect.9.2.6.3
delay(300); // Older spec says you should wait at least 200ms
return rcode;
//return ( ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL));
//return ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL);
}
//set configuration
uint8_t USB::setConf(uint8_t addr, uint8_t ep, uint8_t conf_value) {
return ( ctrlReq(addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL));
return ctrlReq(addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL);
}
#endif // defined(USB_METHODS_INLINE)

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

@ -22,13 +22,11 @@
* Web : http://www.circuitsathome.com
* e-mail : support@circuitsathome.com
*/
#pragma once
#if !defined(_usb_h_) || defined(__ADDRESS_H__)
#ifndef _usb_h_
#error "Never include address.h directly; include Usb.h instead"
#else
#define __ADDRESS_H__
#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) */
@ -63,9 +61,7 @@ struct EpInfo {
//
struct UsbDeviceAddress {
union {
struct {
uint8_t bmAddress : 3; // device address/port number
uint8_t bmParent : 3; // parent hub address
@ -109,26 +105,26 @@ class AddressPoolImpl : public AddressPool {
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;
};
}
// 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++) {
for (uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++)
if (thePool[i].address.devAddress == address)
return i;
}
return 0;
};
// Returns thePool child index for a given parent
return 0;
}
// Return thePool child index for a given parent
uint8_t FindChildIndex(UsbDeviceAddress addr, uint8_t start = 1) {
for (uint8_t i = (start < 1 || start >= MAX_DEVICES_ALLOWED) ? 1 : start; i < MAX_DEVICES_ALLOWED; i++) {
@ -136,14 +132,13 @@ class AddressPoolImpl : public AddressPool {
return i;
}
return 0;
};
}
// Frees address entry specified by index parameter
void FreeAddressByIndex(uint8_t index) {
// Zero field is reserved and should not be affected
if(index == 0)
return;
if (index == 0) return;
UsbDeviceAddress uda = thePool[index].address;
// If a hub was switched off all port addresses should be freed
@ -152,20 +147,19 @@ class AddressPoolImpl : public AddressPool {
FreeAddressByIndex(i);
// If the hub had the last allocated address, hubCounter should be decremented
if(hubCounter == uda.bmAddress)
hubCounter--;
if (hubCounter == uda.bmAddress) hubCounter--;
}
InitEntry(index);
}
// Initializes the whole address pool at once
// Initialize the whole address pool at once
void InitAllAddresses() {
for (uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++)
InitEntry(i);
hubCounter = 0;
};
}
public:
@ -182,31 +176,27 @@ public:
dev0ep.bmNakPower = USB_NAK_MAX_POWER;
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;
if (!addr) return thePool;
uint8_t index = FindAddressIndex(addr);
return index ? thePool + index : NULL;
}
return (!index) ? NULL : thePool + index;
};
// Performs an operation specified by pfunc for each addressed device
// Perform an operation specified by pfunc for each addressed device
void ForEachUsbDevice(UsbDeviceHandleFunc pfunc) {
if(!pfunc)
return;
if (pfunc) {
for (uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++)
if (thePool[i].address.devAddress)
pfunc(thePool + i);
};
}
}
// Allocates new address
// Allocate new address
virtual uint8_t AllocAddress(uint8_t parent, bool is_hub = false, uint8_t port = 0) {
/* if (parent != 0 && port == 0)
@ -217,20 +207,19 @@ public:
//if(parent > 127 || port > 7)
return 0;
if(is_hub && hubCounter == 7)
return 0;
if (is_hub && hubCounter == 7) return 0;
// finds first empty address entry starting from one
uint8_t index = FindAddressIndex(0);
if(!index) // if empty entry is not found
return 0;
if (!index) return 0; // if empty entry is not found
if (_parent.devAddress == 0) {
if (is_hub) {
thePool[index].address.devAddress = 0x41;
hubCounter++;
} else
}
else
thePool[index].address.devAddress = 1;
return thePool[index].address.devAddress;
@ -242,7 +231,8 @@ public:
if (is_hub) {
addr.bmHub = 1;
addr.bmAddress = ++hubCounter;
} else {
}
else {
addr.bmHub = 0;
addr.bmAddress = port;
}
@ -256,9 +246,9 @@ public:
USB_HOST_SERIAL.println(addr.bmAddress, HEX);
*/
return thePool[index].address.devAddress;
};
}
// Empties pool entry
// Empty the pool entry
virtual void FreeAddress(uint8_t addr) {
// if the root hub is disconnected all the addresses should be initialized
@ -266,26 +256,16 @@ public:
InitAllAddresses();
return;
}
uint8_t index = FindAddressIndex(addr);
FreeAddressByIndex(index);
};
FreeAddressByIndex(FindAddressIndex(addr));
}
// 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()
//{
// 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 ++;
// if (thePool[i].address != 0); counter++;
// return counter;
//};
//}
};
#endif // __ADDRESS_H__

View file

@ -22,11 +22,11 @@
* 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:
@ -34,7 +34,7 @@ public:
//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))) {
};
}
};
#define CP_MASK_COMPARE_CLASS 1
@ -69,9 +69,7 @@ class ConfigDescParser : public USBReadParser {
public:
void SetOR(void) {
UseOr = true;
}
void SetOR(void) { UseOr = true; }
ConfigDescParser(UsbConfigXtracter *xtractor);
void Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset);
};
@ -92,10 +90,7 @@ template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTO
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;
while (cntdn) if (!ParseDescriptor(&p, &cntdn)) return;
}
/* Parser for the configuration descriptor. Takes values for class, subclass, protocol fields in interface descriptor and
@ -110,8 +105,7 @@ bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor
valParser.Initialize(&theBuffer);
stateParseDescr = 1;
case 1:
if(!valParser.Parse(pp, pcntdn))
return false;
if (!valParser.Parse(pp, pcntdn)) return false;
dscrLen = *((uint8_t*)theBuffer.pValue);
dscrType = *((uint8_t*)theBuffer.pValue + 1);
stateParseDescr = 2;
@ -139,44 +133,36 @@ bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor
case 4:
switch (dscrType) {
case USB_DESCRIPTOR_CONFIGURATION:
if(!valParser.Parse(pp, pcntdn))
return false;
if (!valParser.Parse(pp, pcntdn)) return false;
confValue = ucd->bConfigurationValue;
break;
case USB_DESCRIPTOR_INTERFACE:
if(!valParser.Parse(pp, pcntdn))
return false;
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;
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)
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;
// if (!valParser.Parse(pp, pcntdn)) return false;
// PrintHidDescriptor((const USB_HID_DESCRIPTOR*)varBuffer);
// break;
default:
if(!theSkipper.Skip(pp, pcntdn, dscrLen - 2))
return false;
if (!theSkipper.Skip(pp, pcntdn, dscrLen - 2)) return false;
}
theBuffer.pValue = varBuffer;
stateParseDescr = 0;
@ -213,6 +199,3 @@ void ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::PrintHidDescrip
}
Notify(PSTR("\r\n"), 0x80);
}
#endif // __CONFDESCPARSER_H__

View file

@ -22,11 +22,11 @@
* Web : http://www.circuitsathome.com
* e-mail : support@circuitsathome.com
*/
#pragma once
#if !defined(_usb_h_) || defined(__HEXDUMP_H__)
#ifndef _usb_h_
#error "Never include hexdump.h directly; include Usb.h instead"
#else
#define __HEXDUMP_H__
#endif
extern int UsbDEBUGlvl;
@ -66,5 +66,3 @@ void HexDumper<BASE_CLASS, LEN_TYPE, OFFSET_TYPE>::Parse(const LEN_TYPE len, con
}
}
}
#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
////////////////////////////////////////////////////////////////////////////////

View file

@ -44,9 +44,7 @@ const uint8_t BulkOnly::epInterruptInIndex = 3;
* @return media capacity
*/
uint32_t BulkOnly::GetCapacity(uint8_t lun) {
if(LUNOk[lun])
return CurrentCapacity[lun];
return 0LU;
return LUNOk[lun] ? CurrentCapacity[lun] : 0UL;
}
/**
@ -56,9 +54,7 @@ uint32_t BulkOnly::GetCapacity(uint8_t lun) {
* @return media sector size
*/
uint16_t BulkOnly::GetSectorSize(uint8_t lun) {
if(LUNOk[lun])
return CurrentSectorSize[lun];
return 0U;
return LUNOk[lun] ? CurrentSectorSize[lun] : 0U;
}
/**
@ -67,9 +63,7 @@ uint16_t BulkOnly::GetSectorSize(uint8_t lun) {
* @param lun Logical Unit Number
* @return true if LUN is ready for use
*/
bool BulkOnly::LUNIsGood(uint8_t lun) {
return LUNOk[lun];
}
bool BulkOnly::LUNIsGood(uint8_t lun) { return LUNOk[lun]; }
/**
* Test if LUN is write protected
@ -77,9 +71,7 @@ bool BulkOnly::LUNIsGood(uint8_t lun) {
* @param lun Logical Unit Number
* @return cached status of write protect switch
*/
bool BulkOnly::WriteProtected(uint8_t lun) {
return WriteOk[lun];
}
bool BulkOnly::WriteProtected(uint8_t lun) { return WriteOk[lun]; }
/**
* Wrap and execute a SCSI CDB with length of 6
@ -145,9 +137,10 @@ uint8_t BulkOnly::MediaCTL(uint8_t lun, uint8_t ctl) {
if (bAddress) {
CDB6_t cdb = CDB6_t(SCSI_CMD_START_STOP_UNIT, lun, ctl & 0x03, 0);
rcode = SCSITransaction6(&cdb, (uint16_t)0, NULL, (uint8_t)MASS_CMD_DIR_OUT);
} else {
SetCurLUN(lun);
}
else
SetCurLUN(lun);
return rcode;
}
@ -238,8 +231,7 @@ bPollEnable(false),
bLastUsbError(0) {
ClearAllEP();
dCBWTag = 0;
if(pUsb)
pUsb->RegisterDeviceClass(this);
if (pUsb) pUsb->RegisterDeviceClass(this);
}
/**
@ -269,16 +261,12 @@ uint8_t BulkOnly::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
ClearAllEP();
AddressPool &addrPool = pUsb->GetAddressPool();
if(bAddress)
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
if (bAddress) return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
// <TECHNICAL>
// Get pointer to pseudo device with address 0 assigned
p = addrPool.GetUsbDevicePtr(0);
if(!p) {
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
}
if (!p) return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
if (!p->epinfo) {
USBTRACE("epinfo\r\n");
@ -298,14 +286,12 @@ uint8_t BulkOnly::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
// Restore p->epinfo
p->epinfo = oldep_ptr;
if(rcode) {
goto FailGetDevDescr;
}
if (rcode) goto FailGetDevDescr;
// Allocate new address according to device class
bAddress = addrPool.AllocAddress(parent, false, port);
if(!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
if (!bAddress) return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// Extract Max Packet Size from the device descriptor
epInfo[0].maxPktSize = udd->bMaxPacketSize0;
@ -315,6 +301,7 @@ uint8_t BulkOnly::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
return USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET;
FailGetDevDescr:
#ifdef DEBUG_USB_HOST
NotifyFailGetDevDescr(rcode);
#endif
@ -322,7 +309,7 @@ FailGetDevDescr:
Release();
return rcode;
};
}
/**
* @param parent (not used)
@ -339,8 +326,7 @@ uint8_t BulkOnly::Init(uint8_t parent __attribute__((unused)), uint8_t port __at
AddressPool &addrPool = pUsb->GetAddressPool();
UsbDevice *p = addrPool.GetUsbDevicePtr(bAddress);
if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
if (!p) return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
// Assign new address to the device
delay(2000);
@ -360,16 +346,14 @@ uint8_t BulkOnly::Init(uint8_t parent __attribute__((unused)), uint8_t port __at
p = addrPool.GetUsbDevicePtr(bAddress);
if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
if (!p) return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
p->lowspeed = lowspeed;
// Assign epInfo to epinfo pointer
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
if(rcode)
goto FailSetDevTblEntry;
if (rcode) goto FailSetDevTblEntry;
USBTRACE2("NC:", num_of_conf);
@ -383,15 +367,12 @@ uint8_t BulkOnly::Init(uint8_t parent __attribute__((unused)), uint8_t port __at
rcode = pUsb->getConfDescr(bAddress, 0, i, &BulkOnlyParser);
if(rcode)
goto FailGetConfDescr;
if (rcode) goto FailGetConfDescr;
if(bNumEP > 1)
break;
if (bNumEP > 1) break;
}
if(bNumEP < 3)
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
if (bNumEP < 3) return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
// Assign epInfo to epinfo pointer
pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
@ -401,15 +382,13 @@ uint8_t BulkOnly::Init(uint8_t parent __attribute__((unused)), uint8_t port __at
// Set Configuration Value
rcode = pUsb->setConf(bAddress, 0, bConfNum);
if(rcode)
goto FailSetConfDescr;
if (rcode) goto FailSetConfDescr;
//Linux does a 1sec delay after this.
delay(1000);
rcode = GetMaxLUN(&bMaxLUN);
if(rcode)
goto FailGetMaxLUN;
if (rcode) goto FailGetMaxLUN;
if (bMaxLUN >= MASS_MAX_SUPPORTED_LUN) bMaxLUN = MASS_MAX_SUPPORTED_LUN - 1;
ErrorMessage<uint8_t> (PSTR("MaxLUN"), bMaxLUN);
@ -421,7 +400,8 @@ uint8_t BulkOnly::Init(uint8_t parent __attribute__((unused)), uint8_t port __at
rcode = Inquiry(lun, sizeof (InquiryResponse), (uint8_t*) & response);
if (rcode) {
ErrorMessage<uint8_t> (PSTR("Inquiry"), rcode);
} else {
}
else {
#if 0
printf("LUN %i `", lun);
uint8_t *buf = response.VendorID;
@ -454,11 +434,11 @@ uint8_t BulkOnly::Init(uint8_t parent __attribute__((unused)), uint8_t port __at
case 6:
printf("T10/1731-D (SPC-4)");
break;
default:
printf("unknown");
default: printf("unknown");
}
printf(" standards.\r\n");
#endif
uint8_t tries = 0xf0;
while ((rcode = TestUnitReady(lun))) {
if (rcode == 0x08) break; // break on no media, this is OK to do.
@ -466,7 +446,8 @@ uint8_t BulkOnly::Init(uint8_t parent __attribute__((unused)), uint8_t port __at
if (tries < 14) {
LockMedia(lun, 1);
MediaCTL(lun, 1); // I actually have a USB stick that needs this!
} else delay(2 * (tries + 1));
} else
delay(2 * (tries + 1));
tries++;
if (!tries) break;
}
@ -478,13 +459,11 @@ uint8_t BulkOnly::Init(uint8_t parent __attribute__((unused)), uint8_t port __at
}
}
CheckMedia();
rcode = OnInit();
if(rcode)
goto FailOnInit;
if (rcode) goto FailOnInit;
#ifdef DEBUG_USB_HOST
USBTRACE("MS configured\r\n\r\n");
@ -496,18 +475,21 @@ uint8_t BulkOnly::Init(uint8_t parent __attribute__((unused)), uint8_t port __at
return 0;
FailSetConfDescr:
#ifdef DEBUG_USB_HOST
NotifyFailSetConfDescr();
goto Fail;
#endif
FailOnInit:
#ifdef DEBUG_USB_HOST
USBTRACE("OnInit:");
goto Fail;
#endif
FailGetMaxLUN:
#ifdef DEBUG_USB_HOST
USBTRACE("GetMaxLUN:");
goto Fail;
@ -568,7 +550,6 @@ void BulkOnly::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t
bNumEP++;
PrintEndpointDescriptor(pep);
}
#else
if ((pep->bmAttributes & bmUSB_TRANSFER_TYPE) == USB_TRANSFER_TYPE_INTERRUPT && (pep->bEndpointAddress & 0x80) == 0x80)
@ -621,25 +602,24 @@ bool BulkOnly::CheckLUN(uint8_t lun) {
for (uint8_t i = 0; i < 8 /*sizeof (Capacity)*/; i++)
D_PrintHex<uint8_t> (capacity.data[i], 0x80);
Notify(PSTR("\r\n\r\n"), 0x80);
// Only 512/1024/2048/4096 are valid values!
uint32_t c = BMAKE32(capacity.data[4], capacity.data[5], capacity.data[6], capacity.data[7]);
if(c != 0x0200LU && c != 0x0400LU && c != 0x0800LU && c != 0x1000LU) {
return false;
}
if (c != 0x0200UL && c != 0x0400UL && c != 0x0800UL && c != 0x1000UL) return false;
// Store capacity information.
CurrentSectorSize[lun] = (uint16_t)(c); // & 0xFFFF);
CurrentCapacity[lun] = BMAKE32(capacity.data[0], capacity.data[1], capacity.data[2], capacity.data[3]) + 1;
if(CurrentCapacity[lun] == /*0xffffffffLU */ 0x01LU || CurrentCapacity[lun] == 0x00LU) {
// Buggy firmware will report 0xffffffff or 0 for no media
if (CurrentCapacity[lun] == /*0xFFFFFFFFUL */ 0x01UL || CurrentCapacity[lun] == 0x00UL) {
// Buggy firmware will report 0xFFFFFFFF or 0 for no media
if (CurrentCapacity[lun])
ErrorMessage<uint8_t> (PSTR(">>>>>>>>>>>>>>>>BUGGY FIRMWARE. CAPACITY FAIL ON LUN"), lun);
return false;
}
delay(20);
Page3F(lun);
if(!TestUnitReady(lun)) return true;
return false;
return !TestUnitReady(lun);
}
/**
@ -653,16 +633,12 @@ void BulkOnly::CheckMedia() {
LUNOk[lun] = false;
continue;
}
if(!LUNOk[lun])
LUNOk[lun] = CheckLUN(lun);
if (!LUNOk[lun]) LUNOk[lun] = CheckLUN(lun);
}
#if 0
printf("}}}}}}}}}}}}}}}}STATUS ");
for(uint8_t lun = 0; lun <= bMaxLUN; lun++) {
if(LUNOk[lun])
printf("#");
else printf(".");
}
for (uint8_t lun = 0; lun <= bMaxLUN; lun++)
printf(LUNOk[lun] ? "#" : ".");
printf("\r\n");
#endif
qNextPollTime = (uint32_t)millis() + 2000;
@ -675,15 +651,9 @@ void BulkOnly::CheckMedia() {
*/
uint8_t BulkOnly::Poll() {
//uint8_t rcode = 0;
if(!bPollEnable)
return 0;
if((int32_t)((uint32_t)millis() - qNextPollTime) >= 0L) {
CheckMedia();
}
if (!bPollEnable) return 0;
if ((int32_t)((uint32_t)millis() - qNextPollTime) >= 0L) CheckMedia();
//rcode = 0;
return 0;
}
@ -718,7 +688,7 @@ uint8_t BulkOnly::Inquiry(uint8_t lun, uint16_t bsize, uint8_t *buf) {
Notify(PSTR("\r\nInquiry\r\n"), 0x80);
Notify(PSTR("---------\r\n"), 0x80);
CDB6_t cdb = CDB6_t(SCSI_CMD_INQUIRY, lun, 0LU, (uint8_t)bsize, 0);
CDB6_t cdb = CDB6_t(SCSI_CMD_INQUIRY, lun, 0UL, (uint8_t)bsize, 0);
uint8_t rc = SCSITransaction6(&cdb, bsize, buf, (uint8_t)MASS_CMD_DIR_IN);
return rc;
@ -820,7 +790,7 @@ uint8_t BulkOnly::RequestSense(uint8_t lun, uint16_t size, uint8_t *buf) {
Notify(PSTR("\r\nRequestSense\r\n"), 0x80);
Notify(PSTR("----------------\r\n"), 0x80);
CDB6_t cdb = CDB6_t(SCSI_CMD_REQUEST_SENSE, lun, 0LU, (uint8_t)size, 0);
CDB6_t cdb = CDB6_t(SCSI_CMD_REQUEST_SENSE, lun, 0UL, (uint8_t)size, 0);
CommandBlockWrapper cbw = CommandBlockWrapper(++dCBWTag, (uint32_t)size, &cdb, (uint8_t)MASS_CMD_DIR_IN);
//SetCurLUN(lun);
return Transaction(&cbw, size, buf);
@ -900,7 +870,7 @@ void BulkOnly::ClearAllEP() {
for (uint8_t i = 0; i < MASS_MAX_SUPPORTED_LUN; i++) {
LUNOk[i] = false;
WriteOk[i] = false;
CurrentCapacity[i] = 0lu;
CurrentCapacity[i] = 0UL;
CurrentSectorSize[i] = 0;
}
@ -953,36 +923,28 @@ uint8_t BulkOnly::HandleUsbError(uint8_t error, uint8_t index) {
}
switch (error) {
// case hrWRONGPID:
case hrSUCCESS:
return MASS_ERR_SUCCESS;
case hrBUSY:
// SIE is busy, just hang out and try again.
return MASS_ERR_UNIT_BUSY;
case hrSUCCESS: return MASS_ERR_SUCCESS;
case hrBUSY: return MASS_ERR_UNIT_BUSY; // SIE is busy, just hang out and try again.
case hrTIMEOUT:
case hrJERR: return MASS_ERR_DEVICE_DISCONNECTED;
case hrSTALL:
if(index == 0)
return MASS_ERR_STALL;
if (index) {
ClearEpHalt(index);
if(index != epDataInIndex)
return MASS_ERR_WRITE_STALL;
return (index == epDataInIndex) ? MASS_ERR_STALL : MASS_ERR_WRITE_STALL;
}
return MASS_ERR_STALL;
case hrNAK:
if(index == 0)
return MASS_ERR_UNIT_BUSY;
return MASS_ERR_UNIT_BUSY;
return index ? MASS_ERR_UNIT_BUSY : MASS_ERR_UNIT_BUSY;
case hrTOGERR:
// Handle a very super rare corner case, where toggles become de-synched.
// I have only ran into one device that has this firmware bug, and this is
// Handle a super rare corner case, where toggles become de-synced.
// I've only run into one device that has this firmware bug, and this is
// the only clean way to get back into sync with the buggy device firmware.
// --AJK
if (bAddress && bConfNum) {
error = pUsb->setConf(bAddress, 0, bConfNum);
if(error)
break;
if (error) break;
}
return MASS_ERR_SUCCESS;
default:
@ -996,7 +958,6 @@ uint8_t BulkOnly::HandleUsbError(uint8_t error, uint8_t index) {
}
#if MS_WANT_PARSER
uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void *buf) {
return Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void *buf, 0);
}
@ -1016,7 +977,6 @@ uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void
, uint8_t flags
#endif
) {
#if MS_WANT_PARSER
uint16_t bytes = (pcbw->dCBWDataTransferLength > buf_size) ? buf_size : pcbw->dCBWDataTransferLength;
printf("Transfersize %i\r\n", bytes);
@ -1026,6 +986,7 @@ uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void
#else
uint16_t bytes = buf_size;
#endif
bool write = (pcbw->bmCBWFlags & MASS_CMD_DIR_IN) != MASS_CMD_DIR_IN;
uint8_t ret = 0;
uint8_t usberr;
@ -1037,9 +998,9 @@ uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void
ret = HandleUsbError(usberr, epDataOutIndex);
//ret = HandleUsbError(pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, sizeof (CommandBlockWrapper), (uint8_t*)pcbw), epDataOutIndex);
if(ret) {
if (ret)
ErrorMessage<uint8_t> (PSTR("============================ CBW"), ret);
} else {
else {
if (bytes) {
if (!write) {
#if MS_WANT_PARSER
@ -1047,25 +1008,22 @@ uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void
uint8_t rbuf[bytes];
while ((usberr = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &bytes, rbuf)) == hrBUSY) delay(1);
if (usberr == hrSUCCESS) ((USBReadParser*)buf)->Parse(bytes, rbuf, 0);
} else {
#endif
while((usberr = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &bytes, (uint8_t*)buf)) == hrBUSY) delay(1);
#if MS_WANT_PARSER
}
else
#endif
{
while ((usberr = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &bytes, (uint8_t*)buf)) == hrBUSY) delay(1);
}
ret = HandleUsbError(usberr, epDataInIndex);
} else {
}
else {
while ((usberr = pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, bytes, (uint8_t*)buf)) == hrBUSY) delay(1);
ret = HandleUsbError(usberr, epDataOutIndex);
}
if(ret) {
ErrorMessage<uint8_t > (PSTR("============================ DAT"), ret);
}
if (ret) ErrorMessage<uint8_t> (PSTR("============================ DAT"), ret);
}
}
{
bytes = sizeof (CommandStatusWrapper);
int tries = 2;
while (tries--) {
@ -1074,18 +1032,20 @@ uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void
ClearEpHalt(epDataInIndex);
if (tries) ResetRecovery();
}
if (!ret) {
Notify(PSTR("CBW:\t\tOK\r\n"), 0x80);
Notify(PSTR("Data Stage:\tOK\r\n"), 0x80);
} else {
}
else {
// Throw away csw, IT IS NOT OF ANY USE.
ResetRecovery();
return ret;
}
ret = HandleUsbError(usberr, epDataInIndex);
if(ret) {
ErrorMessage<uint8_t > (PSTR("============================ CSW"), ret);
}
if (ret) ErrorMessage<uint8_t> (PSTR("============================ CSW"), ret);
if (usberr == hrSUCCESS) {
if (IsValidCSW(&csw, pcbw)) {
//ErrorMessage<uint32_t> (PSTR("CSW.dCBWTag"), csw.dCSWTag);
@ -1093,7 +1053,8 @@ uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void
//ErrorMessage<uint32_t> (PSTR("dCSWDataResidue"), csw.dCSWDataResidue);
Notify(PSTR("CSW:\t\tOK\r\n\r\n"), 0x80);
return csw.bCSWStatus;
} else {
}
else {
// NOTE! Sometimes this is caused by the reported residue being wrong.
// Get a different device. It isn't compliant, and should have never passed Q&A.
// I own one... 05e3:0701 Genesys Logic, Inc. USB 2.0 IDE Adapter.
@ -1105,7 +1066,6 @@ uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void
return MASS_ERR_INVALID_CSW;
}
}
}
return ret;
}
@ -1116,11 +1076,10 @@ uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void
* @return
*/
uint8_t BulkOnly::SetCurLUN(uint8_t lun) {
if(lun > bMaxLUN)
return MASS_ERR_INVALID_LUN;
if (lun > bMaxLUN) return MASS_ERR_INVALID_LUN;
bTheLUN = lun;
return MASS_ERR_SUCCESS;
};
}
/**
* For driver use only.
@ -1147,9 +1106,8 @@ uint8_t BulkOnly::HandleSCSIError(uint8_t status) {
ret = RequestSense(bTheLUN, sizeof (RequestSenseResponce), (uint8_t*) & rsp);
if(ret) {
return MASS_ERR_GENERAL_SCSI_ERROR;
}
if (ret) return MASS_ERR_GENERAL_SCSI_ERROR;
ErrorMessage<uint8_t> (PSTR("Response Code"), rsp.bResponseCode);
if (rsp.bResponseCode & 0x80) {
Notify(PSTR("Information field: "), 0x80);
@ -1201,11 +1159,7 @@ uint8_t BulkOnly::HandleSCSIError(uint8_t status) {
////////////////////////////////////////////////////////////////////////////////
// Debugging code
////////////////////////////////////////////////////////////////////////////////
/**

View file

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

@ -36,37 +36,33 @@ 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);
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);
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);
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);
USB_HOST_SERIAL.print(b
#if !defined(ARDUINO) || ARDUINO < 100
, DEC
#endif
);
//USB_HOST_SERIAL.flush();
}
@ -126,6 +122,7 @@ 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__)
#pragma once
#ifndef _usb_h_
#error "Never include message.h directly; include Usb.h instead"
#else
#define __MESSAGE_H__
#endif
extern int UsbDEBUGlvl;
@ -82,5 +83,3 @@ void ErrorMessage(char const * msg __attribute__((unused)), ERROR_TYPE rcode __a
Notify(PSTR("\r\n"), 0x80);
#endif
}
#endif // __MESSAGE_H__

View file

@ -37,8 +37,7 @@ bool MultiByteValueParser::Parse(uint8_t **pp, uint16_t *pcntdn) {
for (; countDown && (*pcntdn); countDown--, (*pcntdn)--, (*pp)++)
pBuf[valueSize - countDown] = (**pp);
if(countDown)
return false;
if (countDown) return false;
countDown = valueSize;
return true;
@ -52,8 +51,7 @@ bool PTPListParser::Parse(uint8_t **pp, uint16_t *pcntdn, PTP_ARRAY_EL_FUNC pf,
nStage = 1;
case 1:
if(!theParser.Parse(pp, pcntdn))
return false;
if (!theParser.Parse(pp, pcntdn)) return false;
arLen = 0;
arLen = (pBuf->valueSize >= 4) ? *((uint32_t*)pBuf->pValue) : (uint32_t)(*((uint16_t*)pBuf->pValue));
@ -67,11 +65,8 @@ bool PTPListParser::Parse(uint8_t **pp, uint16_t *pcntdn, PTP_ARRAY_EL_FUNC pf,
case 3:
for (; arLenCntdn; arLenCntdn--) {
if(!theParser.Parse(pp, pcntdn))
return false;
if(pf)
pf(pBuf, (arLen - arLenCntdn), me);
if (!theParser.Parse(pp, pcntdn)) return false;
if (pf) pf(pBuf, (arLen - arLenCntdn), me);
}
nStage = 0;

View file

@ -22,11 +22,11 @@
* Web : http://www.circuitsathome.com
* e-mail : support@circuitsathome.com
*/
#pragma once
#if !defined(_usb_h_) || defined(__PARSETOOLS_H__)
#ifndef _usb_h_
#error "Never include parsetools.h directly; include Usb.h instead"
#else
#define __PARSETOOLS_H__
#endif
struct MultiValueBuffer {
uint8_t valueSize;
@ -43,14 +43,12 @@ public:
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;
};
}
bool Parse(uint8_t **pp, uint16_t *pcntdn);
};
@ -63,12 +61,12 @@ class ByteSkipper {
public:
ByteSkipper() : pBuf(NULL), nStage(0), countDown(0) {
};
}
void Initialize(MultiValueBuffer *pbuf) {
pBuf = (uint8_t*)pbuf->pValue;
countDown = 0;
};
}
bool Skip(uint8_t **pp, uint16_t *pcntdn, uint16_t bytes_to_skip) {
switch (nStage) {
@ -80,9 +78,9 @@ public:
if (!countDown)
nStage = 0;
};
}
return (!countDown);
};
}
};
// Pointer to a callback function triggered for each element of PTP array when used with PTPArrayParser
@ -122,8 +120,8 @@ public:
lenSize(0),
valSize(0),
pBuf(NULL),
prsMode(modeArray) {
};
prsMode(modeArray) { }
;
void Initialize(const uint8_t len_size, const uint8_t val_size, MultiValueBuffer * const p, const uint8_t mode = modeArray) {
pBuf = p;
@ -134,15 +132,14 @@ public:
if (prsMode == modeRange) {
arLenCntdn = arLen = 3;
nStage = 2;
} else {
}
else {
arLenCntdn = arLen = 0;
nStage = 0;
}
enStage = 0;
theParser.Initialize(p);
};
}
bool Parse(uint8_t **pp, uint16_t *pcntdn, PTP_ARRAY_EL_FUNC pf, const void *me = NULL);
};
#endif // __PARSETOOLS_H__

View file

@ -22,18 +22,17 @@
* Web : http://www.circuitsathome.com
* e-mail : support@circuitsathome.com
*/
#pragma once
#if !defined(_usb_h_) || defined(__PRINTHEX_H__)
#ifndef _usb_h_
#error "Never include printhex.h directly; include Usb.h instead"
#else
#define __PRINTHEX_H__
#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;
@ -44,16 +43,12 @@ void PrintHex(T val, int lvl) {
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);
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;
@ -64,11 +59,8 @@ void SerialPrintHex(T val) {
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");
if (val < mask) prn->print("0");
mask >>= 4;
}
prn->print((T)val, HEX);
@ -86,7 +78,3 @@ void D_PrintBin(T val, int lvl) {
PrintBin<T > (val, lvl);
#endif
}
#endif // __PRINTHEX_H__

View file

@ -23,12 +23,11 @@
* e-mail : support@circuitsathome.com
*/
#if !defined(_usb_h_) || defined(_ch9_h_)
#ifndef _usb_h_
#error "Never include usb_ch9.h directly; include Usb.h instead"
#else
#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_