From 36772a7ed0c31a99c721d1ea9131a8ecc56a263d Mon Sep 17 00:00:00 2001 From: Andreas Fritiofson Date: Mon, 17 Feb 2014 00:27:09 +0100 Subject: [PATCH] swd: Improve parity calculation and move it to types.h It could be reused by SWD drivers and in other places. Change-Id: Ieed0cf70c111a73d3a42ed59f46a0cdd177a73d5 Signed-off-by: Andreas Fritiofson Reviewed-on: http://openocd.zylin.com/1957 Tested-by: jenkins Reviewed-by: Paul Fertser --- src/helper/types.h | 19 +++++++++++++++++++ src/jtag/swd.h | 13 +------------ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/helper/types.h b/src/helper/types.h index 210d3c3e9..3f0724c3a 100644 --- a/src/helper/types.h +++ b/src/helper/types.h @@ -270,6 +270,25 @@ static inline void buf_bswap32(uint8_t *dst, const uint8_t *src, size_t len) } } +/** + * Calculate the (even) parity of a 32-bit datum. + * @param x The datum. + * @return 1 if the number of set bits in x is odd, 0 if it is even. + */ +static inline int parity_u32(uint32_t x) +{ +#ifdef __GNUC__ + return __builtin_parityl(x); +#else + x ^= x >> 16; + x ^= x >> 8; + x ^= x >> 4; + x ^= x >> 2; + x ^= x >> 1; + return x & 1; +#endif +} + #if defined(__ECOS) /* eCos plain lacks these definition... A series of upstream patches diff --git a/src/jtag/swd.h b/src/jtag/swd.h index c628fa84b..b75a83e36 100644 --- a/src/jtag/swd.h +++ b/src/jtag/swd.h @@ -32,17 +32,6 @@ #define SWD_CMD_PARK (0 << 7) /* not driven by host (pull high) */ /* followed by TRN, 3-bits of ACK, TRN */ -/* pbit16 holds precomputed parity bits for each nibble */ -#define pbit(parity, nibble) ((parity) << (nibble)) - -static const uint16_t pbit16 = - pbit(0, 0) | pbit(1, 1) | pbit(1, 2) | pbit(0, 3) - | pbit(1, 4) | pbit(0, 5) | pbit(0, 6) | pbit(1, 7) - | pbit(1, 8) | pbit(0, 9) | pbit(0, 0xa) | pbit(1, 0xb) - | pbit(0, 0xc) | pbit(1, 0xd) | pbit(1, 0xe) | pbit(0, 0xf); - -#define nibble_parity(nibble) (pbit16 & pbit(1, (nibble))) - /** * Construct a "cmd" byte, in lSB bit order, which swd_driver.read_reg() * and swd_driver.write_reg() methods will use directly. @@ -54,7 +43,7 @@ static inline uint8_t swd_cmd(bool is_read, bool is_ap, uint8_t regnum) | ((regnum & 0xc) << 1); /* 8 cmd bits 4:1 may be set */ - if (nibble_parity(cmd >> 1)) + if (parity_u32(cmd)) cmd |= SWD_CMD_PARITY; /* driver handles START, STOP, and TRN */