gdma_hal_crc_gen.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /*
  2. * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stdint.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. //
  10. // Serially shift {data_in,lfsr_cur} N times to get {lfsr_next}
  11. //
  12. static uint32_t lfsr_serial_shift_crc(uint32_t data_in, uint32_t lfsr_cur,
  13. size_t crc_width, uint32_t crc_poly_hex,
  14. size_t num_bits_to_shift)
  15. {
  16. uint32_t lfsr_next = lfsr_cur;
  17. for (int j = 0; j < num_bits_to_shift; j++) {
  18. uint32_t lfsr_upper_bit = lfsr_next >> (crc_width - 1);
  19. // shift the entire LFSR
  20. for (int i = crc_width - 1; i > 0; i--) {
  21. lfsr_next &= ~(1 << i);
  22. if (crc_poly_hex & (1 << i)) {
  23. // lfsr_next[i] = lfsr_next[i - 1] ^ lfsr_upper_bit ^ data_in[j];
  24. lfsr_next |= (((lfsr_next >> (i - 1)) ^ lfsr_upper_bit ^ (data_in >> j)) & 0x01) << i;
  25. } else {
  26. // lfsr_next[i] = lfsr_next[i - 1];
  27. lfsr_next |= (lfsr_next & (1 << (i - 1))) << 1;
  28. }
  29. }
  30. // lfsr_next[0] = lfsr_upper_bit ^ data_in[j];
  31. lfsr_next &= ~0x01;
  32. lfsr_next |= (lfsr_upper_bit ^ (data_in >> j)) & 0x01;
  33. }
  34. return lfsr_next;
  35. }
  36. void gdma_hal_build_parallel_crc_matrix(int crc_width, uint32_t crc_poly_hex, int data_width,
  37. uint32_t *lfsr_transform_matrix, uint32_t *data_transform_matrix)
  38. {
  39. int N = crc_width;
  40. int M = data_width;
  41. uint32_t lfsr_cur = 0; // N-bit LFSR
  42. uint32_t lfsr_next = 0; // N-bit LFSR
  43. uint32_t data_in = 0; // M-bit data
  44. // LFSR-2-LFSR matrix[NxN], data_in=0
  45. for (int n1 = 0; n1 < N; n1++) {
  46. lfsr_cur = 1 << n1;
  47. lfsr_next = lfsr_serial_shift_crc(data_in, lfsr_cur,
  48. crc_width, crc_poly_hex,
  49. data_width);
  50. lfsr_transform_matrix[n1] = lfsr_next;
  51. }
  52. // Data-2-LFSR matrix[MxN], lfsr_cur=0
  53. lfsr_cur = 0;
  54. for (int m1 = 0; m1 < M; m1++) {
  55. data_in = 1 << m1;
  56. lfsr_next = lfsr_serial_shift_crc(data_in, lfsr_cur,
  57. crc_width, crc_poly_hex,
  58. data_width);
  59. // Invert CRC data bits
  60. data_transform_matrix[M - m1 - 1] = lfsr_next;
  61. }
  62. }
  63. uint32_t gdma_hal_get_data_mask_from_matrix(uint32_t *data_transform_matrix, int data_width, int crc_bit)
  64. {
  65. uint32_t data_mask = 0;
  66. for (int j = 0; j < data_width; j++) {
  67. data_mask |= (data_transform_matrix[j] & (1 << crc_bit)) ? (1 << j) : 0;
  68. }
  69. return data_mask;
  70. }
  71. uint32_t gdma_hal_get_lfsr_mask_from_matrix(uint32_t *lfsr_transform_matrix, int crc_width, int crc_bit)
  72. {
  73. uint32_t lfsr_mask = 0;
  74. for (int j = 0; j < crc_width; j++) {
  75. lfsr_mask |= (lfsr_transform_matrix[j] & (1 << crc_bit)) ? (1 << j) : 0;
  76. }
  77. return lfsr_mask;
  78. }