00001
00013 #ifndef _CO_UTILS_H_
00014 #define _CO_UTILS_H_
00015
00027
00028
00029
00030
00031 #include "compiler.h"
00032 #include <limits.h>
00033 #include "co_math.h"
00034
00035
00036
00037
00038
00046 #define CO_STAIDX_TO_AID(sta_idx) ((sta_idx) + 1)
00047
00056 #define CO_GET_INDEX(__element_ptr, __array_ptr) ((__element_ptr) - (__array_ptr))
00057
00065 #define CO_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
00066
00068 #define CHAR_LEN (CHAR_BIT/8)
00069
00080 #define CPU2HW(ptr) (((uint32_t)(ptr)) * CHAR_LEN)
00081
00090 #define HW2CPU(ptr) ((void *)(((uint32_t)(ptr)) / CHAR_LEN))
00091
00099 #define sizeof_b(a) (sizeof(a) * CHAR_LEN)
00100
00109 #define offsetof_b(a, b) (offsetof(a, b) * CHAR_LEN)
00110
00111
00112
00113
00114
00122 __INLINE uint16_t co_read16(void const *ptr16)
00123 {
00124 return *((uint16_t*)ptr16);
00125 }
00126
00134 __INLINE void co_write16(void const *ptr16, uint32_t value)
00135 {
00136 *(uint16_t*)ptr16 = value;
00137 }
00138
00146 __INLINE uint32_t co_read32(void const *ptr32)
00147 {
00148 return *((uint32_t*)ptr32);
00149 }
00150
00158 __INLINE void co_write32(void const *ptr32, uint32_t value)
00159 {
00160 *(uint32_t*)ptr32 = value;
00161 }
00162
00176 __INLINE void co_copy32(uint32_t *dst, uint32_t *src, uint32_t len)
00177 {
00178 len = CO_ALIGN4_HI(len)/4;
00179 while (len--)
00180 {
00181 *dst++ = *src++;
00182 }
00183 }
00184
00192 __INLINE uint8_t co_read8p(uint32_t addr)
00193 {
00194 #ifdef CFG_RWTL
00195 int shift = (addr & 0x1) * 8;
00196 uint16_t *ptr = (uint16_t *)(addr / 2);
00197 return ((uint8_t)((*ptr >> shift) & 0xFF));
00198 #else
00199 return (*(uint8_t *)addr);
00200 #endif
00201 }
00202
00210 __INLINE void co_write8p(uint32_t addr, uint8_t value)
00211 {
00212 #ifdef CFG_RWTL
00213 int shift = (addr & 0x1) * 8;
00214 uint16_t *ptr = (uint16_t *)(addr / 2);
00215 *ptr = (*ptr & ~(0xFF << shift)) | ((value & 0xFF) << shift);
00216 #else
00217 *(uint8_t *)addr = value;
00218 #endif
00219 }
00220
00221
00229 __INLINE uint16_t co_read16p(uint32_t addr)
00230 {
00231 #ifdef CFG_RWTL
00232 return ((((uint16_t)co_read8p(addr + 1)) << 8) | co_read8p(addr));
00233 #else
00234 struct co_read16_struct
00235 {
00236 uint16_t val __PACKED16;
00237 } *ptr = (struct co_read16_struct*)addr;
00238 return ptr->val;
00239 #endif
00240 }
00241
00249 __INLINE void co_write16p(uint32_t addr, uint32_t value)
00250 {
00251 #ifdef CFG_RWTL
00252 co_write8p(addr, value & 0xFF);
00253 co_write8p(addr + 1, ((value >> 8) & 0xFF));
00254 #else
00255 struct co_read16_struct
00256 {
00257 uint16_t val __PACKED16;
00258 } *ptr = (struct co_read16_struct*) addr;
00259
00260 ptr->val = value;
00261 #endif
00262 }
00263
00271 __INLINE uint32_t co_read24p(uint32_t addr)
00272 {
00273 return ((((uint32_t)co_read16p(addr + 1)) << 8) | co_read8p(addr));
00274 }
00275
00283 __INLINE void co_write24p(uint32_t addr, uint32_t value)
00284 {
00285 co_write8p(addr, value & 0xFF);
00286 co_write16p(addr + 1, ((value >> 8) & 0xFFFF));
00287 }
00288
00296 __INLINE uint32_t co_read32p(uint32_t addr)
00297 {
00298 #ifdef CFG_RWTL
00299 return ((((uint32_t)co_read16p(addr + 2)) << 16) | co_read16p(addr));
00300 #else
00301 struct co_read32_struct
00302 {
00303 uint32_t val __PACKED;
00304 } *ptr = (struct co_read32_struct*) addr;
00305 return ptr->val;
00306 #endif
00307 }
00308
00316 __INLINE void co_write32p(uint32_t addr, uint32_t value)
00317 {
00318 #ifdef CFG_RWTL
00319 co_write16p(addr, value & 0xFFFF);
00320 co_write16p(addr + 2, ((value >> 16) & 0xFFFF));
00321 #else
00322 struct co_read32_struct
00323 {
00324 uint32_t val __PACKED;
00325 } *ptr = (struct co_read32_struct*) addr;
00326 ptr->val = value;
00327 #endif
00328 }
00329
00337 __INLINE uint64_t co_read64p(uint32_t addr)
00338 {
00339 #ifdef CFG_RWTL
00340 return ((((uint64_t)co_read32p(addr + 4)) << 32) | co_read32p(addr));
00341 #else
00342 struct co_read64_struct
00343 {
00344 uint64_t val __PACKED;
00345 } *ptr = (struct co_read64_struct*) addr;
00346 return ptr->val;
00347 #endif
00348 }
00349
00360 __INLINE bool co_cmp8p(uint32_t pkd, uint8_t const *ptr, uint32_t len)
00361 {
00362 while (len--)
00363 {
00364 if (co_read8p(pkd++) != (*ptr++ & 0xFF))
00365 return false;
00366 }
00367 return true;
00368 }
00369
00379 __INLINE void co_pack8p(uint32_t dst, uint8_t const *src, uint32_t len)
00380 {
00381 while (len--)
00382 {
00383 co_write8p(dst++, *src++);
00384 }
00385 }
00386
00396 __INLINE void co_unpack8p(uint8_t *dst, uint32_t src, uint32_t len)
00397 {
00398 while (len--)
00399 {
00400 *dst++ = co_read8p(src++);
00401 }
00402 }
00403
00413 __INLINE void co_copy8p(uint32_t dst, uint32_t src, uint32_t len)
00414 {
00415 while (len--)
00416 {
00417 co_write8p(dst++, co_read8p(src++));
00418 }
00419 }
00420
00431 __INLINE uint8_t co_val_get(uint8_t const array[], int lsb, int width)
00432 {
00433 int msb = lsb + width - 1;
00434 int l_byte_idx = lsb/8;
00435 int m_byte_idx = msb/8;
00436 uint8_t val;
00437
00438 if (m_byte_idx == l_byte_idx)
00439 {
00440 uint8_t mask = CO_BIT(width) - 1;
00441 int shift = lsb % 8;
00442 val = (array[l_byte_idx] >> shift) & mask;
00443 }
00444 else
00445 {
00446 uint8_t l_bits_cnt = m_byte_idx * 8 - lsb;
00447 uint8_t l_mask = CO_BIT(l_bits_cnt) - 1;
00448 uint8_t m_mask = CO_BIT(width - l_bits_cnt) - 1;
00449 int l_shift = lsb % 8;
00450 val = (array[l_byte_idx] >> l_shift) & l_mask;
00451 val |= (array[m_byte_idx] & m_mask) << l_bits_cnt;
00452 }
00453 return (val);
00454 }
00455
00466 __INLINE void co_val_set(uint8_t array[], int lsb, int width, uint8_t val)
00467 {
00468 int msb = lsb + width - 1;
00469 int l_byte_idx = lsb/8;
00470 int m_byte_idx = msb/8;
00471
00472 if (m_byte_idx == l_byte_idx)
00473 {
00474 uint8_t mask = CO_BIT(width) - 1;
00475 int shift = lsb % 8;
00476 array[l_byte_idx] &= ~(mask << shift);
00477 array[l_byte_idx] |= (val & mask) << shift;
00478 }
00479 else
00480 {
00481 uint8_t l_bits_cnt = m_byte_idx * 8 - lsb;
00482 uint8_t l_mask = CO_BIT(l_bits_cnt) - 1;
00483 uint8_t m_mask = CO_BIT(width - l_bits_cnt) - 1;
00484 int l_shift = lsb % 8;
00485 array[l_byte_idx] &= ~(l_mask << l_shift);
00486 array[m_byte_idx] &= ~m_mask;
00487 array[l_byte_idx] |= (val & l_mask) << l_shift;
00488 array[m_byte_idx] |= (val >> l_bits_cnt) & m_mask;
00489 }
00490 }
00491
00501 __INLINE bool co_bit_is_set(uint8_t const array[], int pos)
00502 {
00503 return ((array[pos / 8] & CO_BIT(pos % 8)) != 0);
00504 }
00505
00514 __INLINE void co_bit_set(uint8_t array[], uint8_t pos)
00515 {
00516 array[pos / 8] |= CO_BIT(pos % 8);
00517 }
00518
00527 __INLINE void co_bit_clr(uint8_t array[], uint8_t pos)
00528 {
00529 array[pos / 8] &= ~CO_BIT(pos % 8);
00530 }
00531
00532
00534
00535 #endif // _CO_UTILS_H_