mirror of
https://github.com/marqs85/ossc.git
synced 2024-09-25 22:55:44 +00:00
81 lines
2.9 KiB
C
81 lines
2.9 KiB
C
|
//
|
||
|
// Copyright (C) 2018 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||
|
//
|
||
|
// This file is part of Open Source Scan Converter project.
|
||
|
//
|
||
|
// This program is free software: you can redistribute it and/or modify
|
||
|
// it under the terms of the GNU General Public License as published by
|
||
|
// the Free Software Foundation, either version 3 of the License, or
|
||
|
// (at your option) any later version.
|
||
|
//
|
||
|
// This program is distributed in the hope that it will be useful,
|
||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
// GNU General Public License for more details.
|
||
|
//
|
||
|
// You should have received a copy of the GNU General Public License
|
||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
//
|
||
|
|
||
|
#include "utils.h"
|
||
|
#include "system.h"
|
||
|
#include "io.h"
|
||
|
|
||
|
unsigned char bitswap8(unsigned char v)
|
||
|
{
|
||
|
return ((v * 0x0802LU & 0x22110LU) |
|
||
|
(v * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
|
||
|
}
|
||
|
|
||
|
alt_u32 bswap32(alt_u32 w)
|
||
|
{
|
||
|
return (((w << 24) & 0xff000000) |
|
||
|
((w << 8) & 0x00ff0000) |
|
||
|
((w >> 8) & 0x0000ff00) |
|
||
|
((w >> 24) & 0x000000ff));
|
||
|
}
|
||
|
|
||
|
unsigned long crc32(unsigned char *input_data, unsigned long input_data_length, int do_initialize)
|
||
|
{
|
||
|
unsigned long index;
|
||
|
|
||
|
/* copy of the data buffer pointer so that it can advance by different widths */
|
||
|
void * input_data_copy = (void *)input_data;
|
||
|
|
||
|
/* The custom instruction CRC will initialize to the inital remainder value */
|
||
|
if (do_initialize)
|
||
|
IOWR_32DIRECT(HW_CRC32_0_BASE, 0x0, 0x0);
|
||
|
|
||
|
/* Write 32 bit data to the custom instruction. If the buffer does not end
|
||
|
* on a 32 bit boundary then the remaining data will be sent to the custom
|
||
|
* instruction in the 'if' statement below.
|
||
|
*/
|
||
|
for(index = 0; index < (input_data_length & 0xFFFFFFFC); index+=4)
|
||
|
{
|
||
|
IOWR_32DIRECT(HW_CRC32_0_BASE, 0x4, *(unsigned long *)input_data_copy);
|
||
|
input_data_copy += 4; /* void pointer, must move by 4 for each word */
|
||
|
}
|
||
|
|
||
|
/* Write the remainder of the buffer if it does not end on a word boundary */
|
||
|
if((input_data_length & 0x3) == 0x3) /* 3 bytes left */
|
||
|
{
|
||
|
IOWR_16DIRECT(HW_CRC32_0_BASE, 0x4, *(unsigned short *)input_data_copy);
|
||
|
input_data_copy += 2;
|
||
|
IOWR_8DIRECT(HW_CRC32_0_BASE, 0x4, *(unsigned char *)input_data_copy);
|
||
|
}
|
||
|
else if((input_data_length & 0x3) == 0x2) /* 2 bytes left */
|
||
|
{
|
||
|
IOWR_16DIRECT(HW_CRC32_0_BASE, 0x4, *(unsigned short *)input_data_copy);
|
||
|
}
|
||
|
else if((input_data_length & 0x3) == 0x1) /* 1 byte left */
|
||
|
{
|
||
|
IOWR_8DIRECT(HW_CRC32_0_BASE, 0x4, *(unsigned char *)input_data_copy);
|
||
|
}
|
||
|
|
||
|
/* There are 4 registers in the CRC custom instruction. Since
|
||
|
* this example uses CRC-32 only the first register must be read
|
||
|
* in order to receive the full result.
|
||
|
*/
|
||
|
return IORD_32DIRECT(HW_CRC32_0_BASE, 0x10);
|
||
|
}
|