Files
vhdl/lib/CPUs/MIPS/bsp/examples/barcode.new.c
T
jens 191af92d47 Initial version
Committed on the Free edition of March Hare Software CVSNT Server.
Upgrade to CVS Suite for more features and support:
http://march-hare.com/cvsnt/


git-svn-id: http://moon:8086/svn/vhdl/trunk@790 cc03376c-175c-47c8-b038-4cd826a8556b
2010-03-13 14:13:53 +00:00

323 lines
5.5 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <sys/times.h>
#include <sys/time.h>
#define CPU_FREQ_HZ 100000000
#include "libsys.h"
#include "irq.h"
UINT32 buffer[16384];
#define T_SAMPLE 5000
#define TIMEOUT 1000
typedef struct _bar_t
{
UINT32 T;
UINT32 black;
} bar_t;
enum
{
state_idle = 0,
state_sample,
state_finish
};
bar_t bars[1024];
void bsort(float *pData, UINT32 len)
{
float t;
int i, j;
for(i=len-1; i>=0; i--)
{
for(j=1; j<len; j++)
{
if (pData[j-1] > pData[j])
{
t = pData[j-1];
pData[j-1] = pData[j];
pData[j] = t;
}
}
}
}
typedef struct _smedian_t
{
UINT32 N;
UINT32 is_dirty;
float *pBuf, *pSorted;
UINT32 w;
float median;
} median_t;
void Median_init(median_t *pObj, UINT32 N, float init_val)
{
int i;
pObj->pBuf = (float*)malloc(N*sizeof(float));
pObj->pSorted = (float*)malloc(N*sizeof(float));
for (i=0; i < N; i++)
pObj->pBuf[0] = init_val;
pObj->median = init_val;
pObj->is_dirty = 0;
pObj->w = 0;
pObj->N = N;
}
void Median_free(median_t *pObj)
{
if (pObj->pBuf)
free(pObj->pBuf);
if (pObj->pSorted)
free(pObj->pSorted);
pObj->pBuf = NULL;
pObj->pSorted = NULL;
}
void Median_value_add(median_t *pObj, float value)
{
pObj->is_dirty = 1;
pObj->pBuf[pObj->w++] = value;
if (pObj->w == pObj->N)
pObj->w = 0;
}
float Median_get(median_t *pObj)
{
if (!pObj->is_dirty)
return pObj->median;
memcpy(pObj->pSorted, pObj->pBuf, pObj->N*sizeof(float));
bsort(pObj->pSorted, pObj->N);
if (pObj->N&1)
{
pObj->median = pObj->pSorted[(pObj->N-1)/2];
}
else
{
pObj->median = 0.5f*(pObj->pSorted[pObj->N/2] + pObj->pSorted[pObj->N/2+1]);
}
pObj->is_dirty = 0;
return pObj->median;
}
// -------------------------------------------------------------
UINT32 detect_module(UINT32 T, UINT32 *pBC)
{
UINT32 m, best_M;
float err, kc, best_err;
best_err = 4.f;
best_M = 0;
for (m=0; m < 4; m++)
{
kc = (float)T/pBC[m];
err = fabs(kc - 1);
if (err < best_err)
{
best_M = m+1;
best_err = err;
}
}
return best_M;
}
void handler7(void)
{
UINT32 volatile *pTim_ctrl = (UINT32*)SYS_ITIM_CTRL;
UINT32 volatile *pTim_stat = (UINT32*)SYS_ITIM_STAT;
UINT32 volatile *pPS20_stat = (UINT32*)SYS_PS2_0_STAT;
UINT32 volatile *pPS21_stat = (UINT32*)SYS_PS2_1_STAT;
static UINT32 state, bar_count;
static UINT32 timeout_count, timeout_reload;
static UINT32 white, pin_last, skip, start;
static UINT32 module_cnt_w, module_cnt_b, Tmod0_w, Tmod0_b, M, T0;
float ratio, error, kc;
UINT32 i, j;
static median_t med_b, med_w;
static UINT32 bc_b[4], bc_w[4];
if (*pTim_stat & 1)
{
*pTim_stat = 1;
white = ((*pPS20_stat & SYS_PS2_BIT_PIN_DATA) == 0);
switch (state)
{
case state_idle:
timeout_reload = TIMEOUT;
if (white != pin_last)
{
if (white)
break;
state = state_sample;
module_cnt_b = 0;
module_cnt_w = 0;
Tmod0_w = 0xFFFFFFFF;
Tmod0_b = 0xFFFFFFFF;
bar_count = 0;
Median_init(&med_b, 3, 1);
Median_init(&med_w, 3, 1);
}
break;
case state_sample:
if (!timeout_count)
{
state = state_finish;
break;
}
if (white)
{
module_cnt_w++;
}
else
{
module_cnt_b++;
}
if (white != pin_last)
{
if (pin_last)
{
if (bar_count < 10)
{
if (1.5*module_cnt_w < Tmod0_w)
{
Tmod0_w = module_cnt_w;
}
}
timeout_reload = 10*Tmod0_w;
bars[bar_count].T = module_cnt_w;
bars[bar_count].black = 0;
module_cnt_w = 0;
}
else
{
if (bar_count < 10)
{
if (1.5*module_cnt_b < Tmod0_b)
{
Tmod0_b = module_cnt_b;
}
}
timeout_reload = 10*Tmod0_b;
bars[bar_count].T = module_cnt_b;
bars[bar_count].black = 1;
module_cnt_b = 0;
}
bar_count++;
}
break;
case state_finish:
printf("------------------------------------------------\n");
printf(" Black White \n");
skip = 0;
start = 1;
for (i=0; i < 4; i++)
{
bc_b[i] = (i+1)*Tmod0_b;
bc_w[i] = (i+1)*Tmod0_w;
}
for (i=0; i < bar_count; i++)
{
if (bars[i].black)
{
M = detect_module(bars[i].T, bc_b);
if (M)
{
kc = (float)bars[i].T/bc_b[M-1];
error = kc - 1;
Median_value_add(&med_b, kc);
printf("M=%d, R=%2.2f, E=%+2.2f [%04d]", M, kc, error, bc_b[M-1]);
kc = Median_get(&med_b);
bc_b[M-1] = (UINT32)(kc*bc_b[M-1]);
}
// printf("%d", M);
}
else
{
M = detect_module(bars[i].T, bc_w);
if (M)
{
kc = (float)bars[i].T/bc_w[M-1];
error = kc - 1;
Median_value_add(&med_w, kc);
printf(" M=%d, R=%2.2f, E=%+2.2f [%04d]", M, kc, error, bc_w[M-1]);
kc = Median_get(&med_w);
bc_w[M-1] = (UINT32)(kc*bc_w[M-1]);
}
// printf("%d", M);
printf("\n");
}
}
Median_free(&med_b);
Median_free(&med_w);
if (bar_count)
printf("\n");
state = state_idle;
break;
}
if (white != pin_last)
timeout_count = timeout_reload;
pin_last = white;
if (timeout_count)
timeout_count--;
}
}
int main(void)
{
int i;
UINT32 volatile *pTim_ctrl = (UINT32*)SYS_ITIM_CTRL;
UINT32 volatile *pTim_stat = (UINT32*)SYS_ITIM_STAT;
UINT32 volatile *pTim0_cnt = (UINT32*)SYS_ITIM0_CNT;
UINT32 volatile *pTim0_cmp = (UINT32*)SYS_ITIM0_CMP;
*pTim0_cnt = 0;
*pTim0_cmp = (UINT32)T_SAMPLE;
*pTim_stat = 1;
*pTim_ctrl = 3;
interrupt_register(7, (void*)handler7);
printf("Jenners BarCoder\n");
interrupt_enable(7);
while(1)
{
}
return 0;
}