• No results found

The project has lead to improvements of the WASA experiment on several points. The single discriminator test program has improved the testing of the discriminators.

Allowing a user to perform setup and test of all cards at once and the graphical chart form presented provides a way to check the uniformity of the channels that could not be

performed before. Testing of the discriminators is now faster and more thorough than before.

All solutions about the GUI discussed in chapter 4.1 requires someone/something to be performed in order for the program to create a true view of the “inside” of a crat e. There are many steps on the road that could lead to that the program does not show a true view for the user. The user relies on the program to provide a true view, and will not question the information he receives. With this projects program the user can rely on getting the most important information correct. The most important information will always be what type of cards there are and how many there are of each type. Furthermore the “sticker”

solution does not depend on a technician writing the vital information into a text file or a

database. When the program executes it scans through the crate and delivers just that

information without any need for a database or an existing text file. This leads to the

conclusion that the solution presented in this report is most suitable for now.

REFERENCES

[1] P.Marciniewski, Electronic instrumentation for high energy physics, 1997 Department of Radiation Sciences, Uppsala University, Sweden.

[2] TSL progress report 1996-1997, The Svedberg Laboratory, Uppsala, Sweden.

[3] “http://www.codeguru.com/controls/histogram_control.shtml”

[4] D.Chapman, Teach Yourself Visual C++ 6 in 21 Days, 1998 Sams Publishing.

[5] C.Sphar, Learn Microsoft Visual C++ 6.0 Now, 1999 Microsoft Press.

[6] L.Robison, Teach Yourself Database Programming with Visual C++ 6 in 21 Days, 1999 Sams Publishing.

S.R.Davis, C++ FOR DUMMIES 3

RD

EDITION, 1998 IDG Books Worldwide.

D.McCombs, Detecting the world, 1999 R&D Books.

R.Enander, Föreläsningsanteckningar i C++, 1994 TDB Uppsala University, Sweden.

ACKNOWLEDGEMENTS

The author has had help and guidance during this project. The author would like to

mention these people and thank them for their most appreciated help. First of all the

supervisor of this project Leif Gustafsson, Leif has guided the author along this project

and report, supporting and giving useful tips. Pawel Marciniewski has explained and

helped concerning the hardware used in this project. Mikael Pettersson and Ulf Sporrong

have helped with their knowledge in software and the Visual C++ language.

APPENDIX A

Program code

When the author creates a whole class both header- and source files are presented here. If code have been added in existing functions the source file is presented here. When functions have been added to an already existing class only the function code in the source file is presented here.

Global.h

// HR. Define global variables

#define NR_OF_CARDS 21

#define NR_OF_ADDRESSES 100

#define CHANNELS 16

#define TESTPULSE 0x03

#define TP_AMPLITUDE 10 // Means that it increases 10 times

CChannelsDlg class

Channels1Dlg.h

#if !defined(AFX_CHANNELSDLG1_H__510524F2_604D_11D3_8022_00C04F435307__INCLUDED_)

#define AFX_CHANNELSDLG1_H__510524F2_604D_11D3_8022_00C04F435307__INCLUDED_

#include "HistogramCtrl.h" // Added by ClassView

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000 // ChannelsDlg1.h : header file //

/////////////////////////////////////////////////////////////////////////////

// CChannelsDlg dialog

class CChannelsDlg : public CDialog {

// Construction public:

CChannelsDlg(CWnd* pParent = NULL); // standard constructor // Dialog Data

//{{AFX_DATA(CChannelsDlg) enum { IDD = IDD_CHANNELS };

// NOTE: the ClassWizard will add data members here //}}AFX_DATA

// Overrides

// ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CChannelsDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL

// Implementation protected:

CHistogramCtrl m_CHistogramCtrl; // Variable to get access to public functions in HistogramCtrl class // Generated message map functions

//{{AFX_MSG(CChannelsDlg) virtual BOOL OnInitDialog();

//}}AFX_MSG

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_CHANNELSDLG1_H__510524F2_604D_11D3_8022_00C04F435307__INCLUDED_)

Channels1Dlg.cpp

// ChannelsDlg1.cpp : implementation file

#include "stdafx.h"

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CChannelsDlg dialog

CChannelsDlg::CChannelsDlg(CWnd* pParent /*=NULL*/): CDialog(CChannelsDlg::IDD, pParent) {

//{{AFX_DATA_INIT(CChannelsDlg)

// NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT

// NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP

// CChannelsDlg message handlers BOOL CChannelsDlg::OnInitDialog() {

CDialog::OnInitDialog();

// TODO: Add extra initialization here

CRect rect; // Window area for LTC

GetDlgItem(IDC_STATIC_CHANNELS)->GetWindowRect(rect); // Put window area in IDC_STATIC_CHANNELS ScreenToClient(rect);

m_CHistogramCtrl.Create(WS_VISIBLE | WS_CHILD, rect, this, 100); // Create the HistogramCtrl window

m_CHistogramCtrl.SetRange(0,100); // Set range, max=100 and min=0

for (int i=0; i<=15; i++) // Call the SetPos 16 times, one for each channel m_CHistogramCtrl.SetPos(100, i); // Channel number i

return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000 // Crates.h : header file

/////////////////////////////////////////////////////////////////////////////

// CCrates dialog

class CCrates : public CDialog {

// Construction public:

CCrates(CWnd* pParent = NULL); // standard constructor

// Dialog Data

//{{AFX_DATA(CCrates) enum { IDD = IDD_CRATES };

CButton m_CBCrate9; // Adding variables to the buttons

CButton m_CBCrate8;

// ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CCrates)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL

// Implementation protected:

// Generated message map functions //{{AFX_MSG(CCrates)

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_CRATES_H__99C80C21_69AA_11D3_8022_00C04F435307__INCLUDED_) Crates.cpp

// Crates.cpp : implementation file

#include "stdafx.h"

#include "i2c_debug.h"

#include "Setup.h"

#include "Crates.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CCrates dialog

CCrates::CCrates(CWnd* pParent /*=NULL*/): CDialog(CCrates::IDD, pParent) {

//{{AFX_DATA_INIT(CCrates)

// NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT

}

void CCrates::DoDataExchange(CDataExchange* pDX) {

DDX_Control(pDX, IDC_BCRATE6, m_CBCrate6);

// CCrates message handlers void CCrates::OnExit() {

// TODO: Add your control notification handler code here OnOK();

}

// Function that opens up the Setup dialog when the crate1 button is pressed void CCrates::OnBcrate1()

{

// TODO: Add your control notification handler code here CSetup Setup;

// TODO: Add extra initialization here

HBITMAP hBitmap = (HBITMAP) ::LoadImage(AfxGetInstanceHandle(), "res/crate.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

HBITMAP hBitmap1 = (HBITMAP) ::LoadImage(AfxGetInstanceHandle(), "res/discrate.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE }

CHistogramCtrl class

HistogramCtrl.h // HistogramCtrl.h : header file

#ifndef __HISTOGRAMCTRL_H__

#define __HISTOGRAMCTRL_H__

#include "Global.h"

/////////////////////////////////////////////////////////////////////////////

// CHistogramCtrl window

class CHistogramCtrl : public CDialog {

// Construction

public:

CHistogramCtrl();

UINT m_nVertical;

// Attributes public:

UINT SetPos(UINT nPos, int i);

void SetRange(UINT nLower, UINT nUpper);

void InvalidateCtrl();

// ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CHistogramCtrl)

public:

virtual BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext

= NULL);

//}}AFX_VIRTUAL // Implementation public:

void WichGraph(int g);

void Matrix(int h, int m[NR_OF_CARDS][TP_AMPLITUDE][CHANNELS]);

virtual ~CHistogramCtrl();

// Generated message map functions protected:

UINT m_nPos; // current position within bounds CDC m_MemDC;

// HistogramCtrl.cpp : implementation file

// stdafx.cpp : source file that includes just the standard includes // CPanel.pch will be the pre-compiled header

// stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"

static char THIS_FILE[] = __FILE__;

#endif

int ltc[NR_OF_CARDS][TP_AMPLITUDE][CHANNELS]; // HR. Global variable from Matrix to DrawSpike()

int h; // HR. Global variable from WichGraph to DrawSpike()

/////////////////////////////////////////////////////////////////////////////

BEGIN_MESSAGE_MAP(CHistogramCtrl, CWnd)

// CSpikeCtrl message handlers

BOOL CHistogramCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) {

// TODO: Add your specialized code here and/or call the base class

static CString className = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW);

return CWnd::CreateEx(WS_EX_CLIENTEDGE | WS_EX_STATICEDGE, className, NULL, dwStyle, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top,

pParentWnd->GetSafeHwnd(), (HMENU) nID);

}

void CHistogramCtrl::SetRange(UINT nLower, UINT nUpper) {

ASSERT(nLower >= 0 && nLower < 0xffff);

ASSERT(nUpper > nLower && nUpper < 0xffff);

m_nLower = nLower;

// Small optimization that just invalidates the client area // (The borders don’t usually need updating)

CClientDC dc(this);

CRect rcClient;

GetClientRect(rcClient);

if (m_MemDC.GetSafeHdc() == NULL) {

UINT CHistogramCtrl::SetPos(UINT nPos, int i) // HR. Added int i., the channel number {

if (nPos > m_nUpper) nPos = m_nUpper;

if (nPos < m_nLower) nPos = m_nLower;

UINT nOld = m_nPos;

m_nPos = nPos;

int j = i; // HR

DrawSpike(j); // HR. Added j, channel number

Invalidate();

return nOld;

}

void CHistogramCtrl::OnPaint() {

CPaintDC dc(this); // device context for painting

// TODO: Add your message handler code here // Do not call CWnd::OnPaint() for painting messages // draw scale

CRect rcClient;

GetClientRect(rcClient);

// draw scale

if (m_MemDC.GetSafeHdc() != NULL)

{

dc.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &m_MemDC, 0, 0, SRCCOPY);

} }

void CHistogramCtrl::DrawSpike(int j) {

//CClientDC dc(this);

UINT nRange = m_nUpper - m_nLower;

CRect rcClient;

GetClientRect(rcClient);

if (m_MemDC.GetSafeHdc() != NULL) {

// HR Widht, 16 was original 4

m_MemDC.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &m_MemDC, 16, 0, SRCCOPY);

// Following three lines is “marked out” by HR

//CRect rcTop(rcClient.right - 4, 0, rcClient.right - 2, rcClient.bottom);

//rcTop.top = (long) (((float) (m_nPos - m_nLower) / nRange) * rcClient.Height());

//rcTop.top = rcClient.bottom - rcTop.top;

// draw scale

CRect rcRight = rcClient;

rcRight.left = rcRight.right - 4;

m_MemDC.SetBkColor(RGB(0,0,0));

CBrush bkBrush(HS_HORIZONTAL,RGB(0,128,0)); // RGB(0,128,0) m_MemDC.FillRect(rcRight,&bkBrush);

int H=5; // HR Variables to split spike in 10 segments

int B=50; // HR. ||

-// HR. Looping through each segment and fill with the right color for (int i=0; i<TP_AMPLITUDE; i++)

{

CRect rcTop(rcClient.right - 9, 0, rcClient.right - 2, B); // Was rcClient.bottom);

// (left, top, right, bottom) of the rectangle rcTop.top = (long) (((float) (m_nPos - m_nLower) / nRange) * H); // Was rcClient.Height());

rcTop.top = rcClient.bottom - rcTop.top;

// draw current spike, h=cardnumber, i=testpulse amplitud, j=channelnumber

if (ltc[h][i][j]==0) // If channel not reacted fill with red {

CBrush rbrush(RGB(255,0,0)); // Create red brush m_MemDC.FillRect(rcTop, &rbrush); // Fill rectangle }

if (ltc[h][i][j]==1) // If channel reacted fill with green {

CBrush brush(RGB(0,255,0)); // Create green brush m_MemDC.FillRect(rcTop, &brush); // Fill rectangle }

// Function that saves matrix LTC from SingleDiscrim::OnTest to gloabal variable (matrix) ltc

void CHistogramCtrl::Matrix(int h, int m[NR_OF_CARDS][TP_AMPLITUDE][CHANNELS]) // h==cardnumber {

for (int i=0; i<TP_AMPLITUDE; i++) for (int j=0; j<CHANNELS; j++)

ltc[h][i][j]=m[h][i][j];

}

// Function that receives the number of the selected card

void CHistogramCtrl::WichGraph(int g) // g==selected boardaddress

{

h = g; // saves boardaddress into global variable h for use in DrawSpike(int j) }

CMainFrame class

MainFrame.cpp

void CMainFrame::OnAppCrates() {

// TODO: Add your command handler code here CCrates Crates;

#include "SingleDebug.h" // Added by ClassView

#include "ChannelsDlg1.h" // Added by ClassView

#include "SingleDiscrim.h" // Added by ClassView

#include "HistogramCtrl.h" // Added by ClassView

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000 // Setup.h : header file //

/////////////////////////////////////////////////////////////////////////////

// CSetup dialog

class CSetup : public CDialog {

// Construction public:

CSetup(CWnd* pParent = NULL); // standard constructor // Dialog Data

// Overrides

// ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CSetup)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL

// Implementation protected:

void OnOff(int c);

CSingleDebug m_CSingleDebug; // To be able to see how many cards there is CChannelsDlg m_CChannelsDlg; // To be able to open the CChannelsDlg dialog SingleDiscrim m_CSingleDiscrim; // To be able to open the CSingleDiscrim dialog CHistogramCtrl m_CHistogramCtrl;

// Generated message map functions //{{AFX_MSG(CSetup)

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_SETUP_H__10CA0023_5ECD_11D3_8022_00C04F435307__INCLUDED_) Setup.cpp

// Setup.cpp : implementation file //

#include "stdafx.h"

#include "I2C_Debug.h"

#include "Global.h" // Includes global variables

#include "Setup.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

// Array for holding type of cards in the crate

int crate[NR_OF_CARDS]; // NR_OF_CARDS is a global variable

/////////////////////////////////////////////////////////////////////////////

// CSetup dialog

CSetup::CSetup(CWnd* pParent /*=NULL*/): CDialog(CSetup::IDD, pParent) {

//{{AFX_DATA_INIT(CSetup)

m_i16ChDelay = 0; // Default value

m_i16ChDiscrim = 0;

DDX_Control(pDX, IDC_ONOFFC11, m_CBSlot11);

// CSetup message handlers

void CSetup::OnExit() // Exits the program

{

// TODO: Add your control notification handler code here OnOK();

}

BOOL CSetup::OnInitDialog() {

CDialog::OnInitDialog();

// TODO: Add extra initialization here // Set the default values

m_i16ChDiscrim = 0;

for (int i=0; i<NR_OF_CARDS; i++) // Fill crate array with zeros as default crate[i]=0;

m_CSingleDebug.OnNrofcards(crate); // Get the number of addresses in crate from CSingleDebug for (i=0; i<NR_OF_CARDS; i++) // Loop to set the values of the slots {

if (crate[i] == 1) // If 16-channel discriminator card

m_i16ChDiscrim++;

if (crate[i] == 2) // If 16-channel delay card

m_i16ChDelay++;

if (crate[i] == 3 ) // If universal trigger logic card

m_iUtl++;

OnOff(i); // Call OnOff to color the slots in the crate showing the type of card in slot number i }

// Get handle to the bitmap and put it on the view button

HBITMAP hBitmap = (HBITMAP) ::LoadImage(AfxGetInstanceHandle(), "res/graph.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

m_CBView.SetBitmap(hBitmap);

UpdateData(FALSE); // Updates the dialog window values

return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE }

// Function that colors the slots in the crate

void CSetup::OnOff(int c) // Variable c is the current slot

{

// Get handle to the different bitmaps

HBITMAP hBitmapG = (HBITMAP) ::LoadImage(AfxGetInstanceHandle(), "res/discrim.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

HBITMAP hBitmapC = (HBITMAP) ::LoadImage(AfxGetInstanceHandle(), "res/delay.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

HBITMAP hBitmapY = (HBITMAP) ::LoadImage(AfxGetInstanceHandle(), "res/tlogic.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

switch (c) // c is the slot number

{

case 0:

{

if (crate[c] == 1) // 16-channel discriminator

m_CBSlot1.SetBitmap(hBitmapG); // Green bitmap

if (crate[c] == 2) // 16-channel delay

m_CBSlot1.SetBitmap(hBitmapC); // Cyan bitmap

if (crate[c] == 3) // Universal trigger logic

m_CBSlot1.SetBitmap(hBitmapY); // Yellow bitmap }

}

}

}

// Function that launches the SingleDiscrim class for setup and testing of the cards void CSetup::OnSetupTest()

{

// TODO: Add your control notification handler code here m_CSingleDiscrim.DoModal();

}

void CSetup::OnView() {

// TODO: Add your control notification handler code here UpdateData(TRUE);

m_CHistogramCtrl.WichGraph(m_iBoardaddr); // Sends the board address of the card for showing the graph m_CChannelsDlg.DoModal();

// TODO: Add your control notification handler code here

ofstream outFile("addresses.txt"); // Creating an text file for writing

int addresses[NR_OF_ADDRESSES]; // NR_OF_ADDRESSES is a global variable for (int i=0; i<NR_OF_ADDRESSES; i++) // Fill with zeros as default

addresses[i] = 0;

// Creating one hex number out of two. addr1 higher bits and addr2 lower bits. OR is used addr = (addr1<<8) | addr2;

addresses[n] = addr;

} }

err = 0;

for (i=0; i<=n; i++)

outFile << addresses[i] << "\n"; // print every board address to the text file outFile.close();

n = 0;

for (i=0; i<NR_OF_ADDRESSES; i++) {

if ((addresses[i] >= 0xf000) && (addresses[i]<0xf0ff)) // if 16-ch discrim card put a 1 in crate[n]

if ((addresses[i]-0xf000)%4 == 0) {

crate[n] = 1;

n++;

}

if ((addresses[i] >= 0xfa10) && (addresses[i]<0xfaff)) // if 16-ch delay card put a 2 in crate[n]

if ((addresses[i]-0xfa10)%16 == 0) {

crate[n] = 2;

n++;

}

if ((addresses[i] >= 0xf4e0) && (addresses[i]<0xfa00)) // if universal trigger logic card put a 3 in crate[n]

if ((addresses[i]-0xfa10)%16 == 0) {

crate[n] = 3;

n++;

} }

m_CSingleDiscrim.Boardaddr(addresses); // Sends the addresses to SingleDiscrim class }

void CSingleDebug::OnNextaddr() {

// TODO: Add your control notification handler code here

UpdateData(TRUE); // update the variables

//the input string is returned as hex

sscanf(m_strAddr1Single, "%x", &address1);

sscanf(m_strAddr2Single, "%x", &address2);

address2 = address2 + 1 ;

for (addr1 = address1; addr1<=0xff; addr1++) {

result = div (addr1,2);

if(result.rem==0) // Only even address1 is processed {

err = I2C_openbus() ; if (err == 1) {

mes = MessageBox ("Power is off", "Error",MB_ICONHAND) ; I2C_closebus() ;

UpdateData(FALSE);

return ; }

err = I2C_write(addr1,speed) ; I2C_closebus() ;

if (err == 0) {

// write m_strI2CAdr1 in the dialog wsprintf(szMsg, "%x", addr1);

m_strAddr1Single = szMsg;

for (addr2 = address2; addr2<=0xff; ++addr2) {

// write m_strI2CAdr2 in the dialog wsprintf(szMsg, "%x", addr2);

}

address2 = 0 ; // Reinitialize }

}

MessageBox ("No more modules atached");

UpdateData(FALSE);

}

SingleDiscrim class

SingleDiscrim.cpp

// SingleDiscrim.cpp : implementation file //

#include "stdafx.h"

#include "I2C_Debug.h"

#include "I2C_util.h"

#include "Global.h" // HR. Includes the global variables

#include "SingleDiscrim.h"

#include "mmp.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

// HR. Class global variables

int test[NR_OF_CARDS]; // HR. Array for holding number of cards

int address[NR_OF_ADDRESSES]; // HR. Array for the addresses

/////////////////////////////////////////////////////////////////////////////

// SingleDiscrim dialog

SingleDiscrim::SingleDiscrim(CWnd* pParent /*=NULL*/): CDialog(SingleDiscrim::IDD, pParent) {

}

// SingleDiscrim message handlers void SingleDiscrim::OnRunSetup() {

// TODO: Add your control notification handler code here

UpdateData(TRUE); //update variables

// HR. Default matrix for drawing the channels graph

for (int H=0; H<NR_OF_CARDS; H++) // Loop through the cards

for (int i=0; i<TP_AMPLITUDE; i++) // Loop through the testpulse ampltiudes for (int j=0; j<CHANNELS; j++) // Loop through the channels

{

LTC[H][i][j]=0; // Low Threshold Check

HTC[H][i][j]=0; // High Threshold Check

}

if (m_bAllCards == TRUE) // HR. Test all cards

{

for (int n=0; n<NR_OF_ADDRESSES; n++) // Loop through every address {

// If valid address axtract the cards board address

if ((address[n] < 0xf0ff) && ((address[n]-0xf000)%4 == 0) && (address[n] != 0)) {

m_DeviceSpin.SetPos(((address[n]-0xf000)/4)); // Set the current board adress

UpdateData(TRUE); // Updates the dat

// HR: Enables IDC_DEVSEL and IDC_DEVICE GetDlgItem(IDC_DEVSEL)->EnableWindow(FALSE);

GetDlgItem(IDC_DEVICE)->EnableWindow(FALSE);

sscanf(m_strDevice,"%d", &device); // Scans the board address speed1 = 0;

addr1 = 0xf0;

addr2 = 4*(device); // Device == board address

// Formatting output data for (i=0; i<=3; i++)

disc_data[3-i] = 16 * durat + ch_mask[i];

// Channel mask and duration data transfer

//mes1 = MessageBox ("Power is off", "Error",MB_ICONHAND) ; MessageBox ("Power is off", "Error",MB_ICONHAND) ;

return; // HR. Exit function to avoid looping through the error message }

if (err1 ==2)

mes1 = MessageBox ("Wrong 1st address WR", "Error",MB_ICONHAND);

if (err1 ==3)

mes1 = MessageBox ("Wrong 2nd address WR", "Error",MB_ICONHAND);

if (err1 ==4)

mes1 = MessageBox ("Missing acknowledge", "Error",MB_ICONHAND);

pgot_data = &got_data[0];

err1 = I2C_receive(addr1,addr2+2,speed1,4,pgot_data);

if (err1 ==1)

mes1 = MessageBox ("Power is off", "Error",MB_ICONHAND);

if (err1 ==2)

mes1 = MessageBox ("Wrong 1st address WR", "Error",MB_ICONHAND);

if (err1 ==3)

mes1 = MessageBox ("Wrong 2nd address WR", "Error",MB_ICONHAND);

//error counter for (i=0 ; i<=3 ; ++i)

if (got_data[i] != disc_data[i])

mes1 = MessageBox ("Transfer error1",

"Error",MB_ICONHAND) ; ////////////////////////////////////////////

// Threshold Programming and read back //

////////////////////////////////////////////

err_tot1 = 0;

err1 = load_DAC(addr1,addr2,0x0f,0xff,speed1) ; // reference voltage err_tot1 = err_tot1 + err1 ;

err1 = load_DAC(addr1,addr2,0x0b,0x20,speed1) ; // testpulse amplitude err_tot1 = err_tot1 + err1 ;

err1 = load_DAC(addr1,addr2,0x03,threshlo,speed1) ; // low threshold err_tot1 = err_tot1 + err1 ;

err1 = load_DAC(addr1,addr2,0x07,threshhi,speed1) ; // hi threshold err_tot1 = err_tot1 + err1 ;

if (err_tot1 > 0) {

mes1 = MessageBox ("Transfer error2", "Error",MB_ICONHAND) ; return ;

}

threshlo_rd = read_ADC(addr1,addr2+1,0xcf,speed1); //read low threshold threshhi_rd = read_ADC(addr1,addr2+1,0x8f,speed1); //read high threshold OnTest(device); // HR. Send card with board address = device for testing } // End of if statement

} // End of for loop

GetDlgItem(IDC_DEVSEL)->EnableWindow(TRUE); // HR. Enables control IDC_DEVSEL GetDlgItem(IDC_DEVICE)->EnableWindow(TRUE); // HR. Enables control IDC_DEVICE } // End of if "testing all the cards" statement

else // Test a specific card

{

speed1 = 0;

addr1 = 0xf0;

addr2 = 4*device; // device gives the proper boardaddress

// Formatting output data for (i=0; i<=3; i++)

disc_data[3-i] = 16 * durat; // + ch_mask[i];

// Channel mask and duration data transfer err1 = 0;

pdisc_data = &disc_data[0];

err1 = I2C_send(addr1,addr2+2,speed1,4,pdisc_data);

if (err1 ==1) {

mes1 = MessageBox ("Power is off", "Error",MB_ICONHAND) ; return;

}

if (err1 ==2)

mes1 = MessageBox ("Wrong 1st address WR", "Error",MB_ICONHAND) ; if (err1 ==3)

mes1 = MessageBox ("Wrong 2nd address WR", "Error",MB_ICONHAND) ; if (err1 ==4)

mes1 = MessageBox ("Missing acknowledge", "Error",MB_ICONHAND) ; pgot_data = &got_data[0];

err1 = I2C_receive(addr1,addr2+2,speed1,4,pgot_data);

if (err1 ==1)

mes1 = MessageBox ("Power is off", "Error",MB_ICONHAND) ; if (err1 ==2)

mes1 = MessageBox ("Wrong 1st address WR", "Error",MB_ICONHAND) ; if (err1 ==3)

mes1 = MessageBox ("Wrong 2nd address WR", "Error",MB_ICONHAND) ; //error counter

for (i=0 ; i<=3 ; ++i)

if (got_data[i] != disc_data[i])

mes1 = MessageBox ("Transfer error1", "Error",MB_ICONHAND) ; ////////////////////////////////////////////

// Threshold Programming and read back //

////////////////////////////////////////////

err_tot1 = 0;

err1 = load_DAC(addr1,addr2,0x0f,0xff,speed1) ; // reference voltage err_tot1 = err_tot1 + err1 ;

err1 = load_DAC(addr1,addr2,0x0b,0x20,speed1) ; // test pulse amplitude err_tot1 = err_tot1 + err1 ;

err1 = load_DAC(addr1,addr2,0x03,threshlo,speed1) ; // low threshold err_tot1 = err_tot1 + err1 ;

err1 = load_DAC(addr1,addr2,0x07,threshhi,speed1) ; // hi threshold err_tot1 = err_tot1 + err1 ;

if (err_tot1 > 0) {

mes1 = MessageBox ("Transfer error2", "Error",MB_ICONHAND) ; return ;

}

threshlo_rd = read_ADC(addr1,addr2+1,0xcf,speed1); //read low threshold threshhi_rd = read_ADC(addr1,addr2+1,0x8f,speed1); //read high threshold // HR. Check to see if thresholds differs more than 2 mV

if (threshlo_rd < (threshlo-1) || threshlo_rd > (threshlo+1))

MessageBox("Low threshold differs more than 1 mV", "Warning", MB_ICONEXCLAMATION);

if (threshhi_rd < (threshhi-1) || threshhi_rd > (threshhi+1))

MessageBox("High threshold differs more than 1 mV", "Warning!", MB_ICONEXCLAMATION);

wsprintf(szMsg1, " Programming done \n\n Low threshold is : %d \n High threshold is :

%d", threshlo_rd, threshhi_rd);

MessageBox (szMsg1);

OnTest(device); // Test card with board address = device

} // End of else statement m_strDevice = "0";

UpdateData(FALSE); // Update the dialog window } // End of OnRunSetup()

BOOL SingleDiscrim::OnInitDialog() {

CDialog::OnInitDialog();

// TODO: Add extra initialization here if(MMPOpen())

{

MessageBox("Can’t open the driver", "OK", MB_OK|MB_ICONINFORMATION);

}

void SingleDiscrim::OnOK() {

// TODO: Add extra validation here MMPClose();

CDialog::OnOK();

}

void SingleDiscrim::OnTest(int h) // HR. h = device = board address {

// TODO: Add your control notification handler code here pgot_data = &got_data[0];

for (int m=0; m<TP_AMPLITUDE; m++) // HR. Loop through all testpulse amplitudes {

err1 = load_DAC(addr1,addr2,0x0b,TESTPULSE+m,speed1) ; // TESTPULSE is a global variable if( err1 == 1)

mes1 = MessageBox ("Error", "Error",MB_ICONHAND) ; pgot_data = &got_data[0];

err1 = I2C_receive(addr1,addr2+3,speed1,4,pgot_data);

if (err1 ==1)

mes1 = MessageBox ("Power is off", "Error",MB_ICONHAND) ; if (err1 ==2)

mes1 = MessageBox ("Wrong 1st address WR", "Error",MB_ICONHAND) ; if (err1 ==3)

mes1 = MessageBox ("Wrong 2nd address WR", "Error",MB_ICONHAND) ; // HR. Fill the matrix with discriminator values

for (int a=0; a<=1; a++) {

if (a==0) // HR. channels 0-7

{

int n=1;

for (int i=8; i<=15; i++) // HR. Check the threshold values {

if ((got_data[a] & n) == n)

LTC[h][m][i]=1; // Low threshold if ((got_data[a+2] & n) == n)

HTC[h][m][i]=1; // High threshold

n=2*n; // n = 1,2,4,8,16,...

for (int i=0; i<=7; i++) // HR. Check the threshold values { } // End of AMPLITUDES for loop // HR. Check to see if some channel is dead for (int j=0; j<CHANNELS; j++) {

int sum = 0;

char szMsg5[30];

for (i=0; i<TP_AMPLITUDE; i++) // Go through every amplitude sum = sum + LTC[h][i][j]; // LTC[][][] = 1 if channel reacted if (sum == 0)

{

wsprintf(szMsg5, "Check card with boardaddress %d", device);

MessageBox(szMsg5);

j = CHANNELS; // Exit to prevent 15 messages if the whole card is broke }

}

// HR. Send matrix to HistogramCtrl class for drawing the chart, h=device=boardaddress m_CHistogramCtrl.Matrix(h, LTC);

}

// HR. Function that receives the board addresses from CSingleDebug class void SingleDiscrim::Boardaddr(int baddr[NR_OF_ADDRESSES]) {

for (i=0; i<NR_OF_ADDRESSES; i++)

address[i] = baddr[i]; // Copy addresses in to class-global variable address[]

}

Related documents