Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Test.cpp
- Committer:
- Nasungil
- Date:
- 2017-11-24
- Revision:
- 1:f23d9ead1017
- Parent:
- 0:f7ea94750875
- Child:
- 2:4a75bdce2735
File content as of revision 1:f23d9ead1017:
#include "NM500.h"
#include "Test.h"
#include "mbed.h"
#include "SDFileSystem.h"
SDFileSystem sd(SD_MOSI, SD_MISO, SD_SCK, SD_CS, "sd"); // the pinout on the mbed Cool Components workshop board
FILE *fp=NULL;
DigitalOut SDCard_CS(D10);
unsigned char vector[NEURONSIZE];
extern int NSR_Conn_fail;
extern int GCR_Conn_fail;
extern int MINIF_Conn_fail;
extern int MAXIF_Conn_fail;
extern int AIF_Conn_fail;
extern int NCR_Conn_fail;
extern int Memory_fail;
extern int Connection;
extern int Reset_fail;
extern int CMN_Nsr;
extern int CMN_RC;
extern int aif_fail;
extern int ncount_fail;
extern int id_fail;
extern int nsr_fail;
extern int Nid1;
extern int Nid2;
extern int Dist1;
extern int Dist2;
extern int Gcr1;
extern int Gcr2;
extern int Aif1;
extern int Aif2;
extern int Minif1;
extern int Minif2;
extern int Maxif1;
extern int Maxif2;
extern int Cat1;
extern int Cat2;
extern int Memory1;
extern int Memory2;
extern unsigned char array1[NEURONSIZE];
extern unsigned char array2[NEURONSIZE];
extern int Learn1;
extern int Learn2;
//SPI init
void SD_Init(void)
{
//test CS
SDCard_CS = HIGH; //disable
wait(0.1);
mkdir("/sd", 0777);
fp = fopen("/sd/data.txt", "w");
if(fp == NULL)
{
error("Could not open file for write\n");
}
fclose(fp);
printf("SD Init OK\n");
}
void RESET_Test(void)
{
printf("\nRESET Test\n");
//nomal mode
//printf("NOMAL MODE \n");
int nsr = read(NM_NSR);
//printf("NSR : 0x%x \n",nsr);
int gcr = read(NM_GCR);
//printf("GCR : 0x%x \n",gcr);
int minif = read(NM_MINIF);
//printf("MINIF : 0x%x \n",minif);
int maxif = read(NM_MAXIF);
//printf("MAXIF : 0x%x \n",maxif);
int dist = read(NM_DIST);
//printf("dist : 0x%x \n",dist);
int cat = read(NM_CAT);
//printf("cat : 0x%x \n",cat);
int ncount = read(NM_NCOUNT);
//printf("ncount : 0x%x \n",ncount);
//sr mode
// printf("\nSR MODE \n");
write(NM_NSR,0x10);
// int comp = read(NM_COMP);
// printf("COMP : 0x%x \n",comp);
//nsr = read(NM_NSR);
//printf("NSR : 0x%x \n",nsr);
//minif = read(NM_MINIF);
//printf("MINIF : 0x%x \n",minif);
int ncr = read(NM_NCR);
//printf("ncr : 0x%x \n",ncr);
//dist = read(NM_DIST);
//printf("dist : 0x%x \n",dist);
//cat = read(NM_CAT);
//printf("cat : 0x%x \n",cat);
int aif = read(NM_AIF);
//printf("aif : 0x%x \n",aif);
int nid = read(NM_NID);
//printf("nid : 0x%x \n",nid);
write(NM_NSR,0x00);
if(nsr != 0x00)
Reset_fail = 1;
if(gcr != 0x01)
Reset_fail = 1;
if(minif != 0x02)
Reset_fail = 1;
if(maxif != 0x4000)
Reset_fail = 1;
if(dist != 0xffff)
Reset_fail = 1;
if(cat != 0xffff)
Reset_fail = 1;
if(ncr != 0x01)
Reset_fail = 1;
if(aif != 0x4000)
Reset_fail = 1;
if(nid != 0x0000)
Reset_fail = 1;
if(Reset_fail == 0)
printf("Reset Test Pass\n");
else{
printf("Reset Test Fail\n");
printf("Reset the NM500 and proceed\n");
}
}
//각 레지스터의 데이터가 깨지는 것이 없는지 확인
void Connection_test(void)
{
///////////NSR 시작//////////////
printf("\nConnection Test\n");
// //기존 NSR 백업
// //int init_NSR = read(NM_NSR);
// //NSR의 데이터에 0xaa write
// write(NM_NSR, 0xaa);
// //사용하는 비트만 & 연산
// int temp_NSR = read(NM_NSR)& 0x3f;
// //printf("NSR : 0x%x\n", temp_NSR);
// if(temp_NSR != 0x2a){
// printf("NSR Connection error\n");
// NSR_Conn_fail=1;
// Connection = 1;
// }
//
// //NSR의 데이터를 0x55로 변경하여 write
// write(NM_NSR, 0x055);
// temp_NSR = read(NM_NSR)&0x3f;
// //printf("NSR : 0x%x\n",temp_NSR);
// if(temp_NSR != 0x19){
// printf("NSR Connection error\n");
// NSR_Conn_fail=1;
// Connection = 1;
// }
//// if(NSR_Conn_fail == 0)
//// printf("NSR_Connetion PASS \n");
//
// //NSR을 초기 저장값으로 복원
// write(NM_NSR, 0);
////////////NSR 종료////////////
///////////GCR 시작//////////////
//write GCR 0xaa
write(NM_GCR, 0xaa);
//GCR Read
unsigned int temp_GCR = read(NM_GCR);
// printf("GCR : 0x%x\n", temp_GCR);
//GCR data가 깨졌을 경우
if(temp_GCR != 0xaa){
GCR_Conn_fail = 1;
Connection = 1;
printf("GCR Connection error\n");
}
//write GCR 0x55
write(NM_GCR, 0x55);
temp_GCR = read(NM_GCR);
//printf("GCR : 0x%x\n", temp_GCR);
//GCR data가 깨졌을 경우
if(temp_GCR != 0x55){
GCR_Conn_fail = 1;
Connection = 1;
printf("GCR Connection error\n");
}
///////////GCR 종료//////////////
///////////MINIF 시작//////////////
write(NM_MINIF, 0xaaaa);
int temp_MINIF = read(NM_MINIF);
//printf("MINIF : 0x%x\n", temp_MINIF);
//minif data 확인
if(temp_MINIF != 0xaaaa){
MINIF_Conn_fail = 1;
Connection = 1;
printf("MINIF Connection error\n");
}
//write MINIF 0x55
write(NM_MINIF, 0x5555);
temp_MINIF = read(NM_MINIF);
//printf("MINIF : 0x%x\n", temp_MINIF);
//MINIF test
if(temp_MINIF != 0x5555){
MINIF_Conn_fail = 1;
Connection = 1;
printf("MINIF Connection error\n");
}
//////////END MINIF/////////////////
///////////MAXIF 시작//////////////
//write maxif 0xaaaa
write(NM_MAXIF, 0xaaaa);
int temp_MAXIF = read(NM_MAXIF);
//printf("MAXIF : 0x%x\n", temp_MAXIF);
//maxif data 확인
if(temp_MAXIF != 0xaaaa){
MAXIF_Conn_fail = 1;
Connection = 1;
printf("MAXIF Connection error\n");
}
//write MAXIF 0x55
write(NM_MAXIF, 0x5555);
temp_MAXIF = read(NM_MAXIF);
//printf("MAXIF : 0x%x\n", temp_MAXIF);
//MAXIF test
if(temp_MAXIF != 0x5555){
MAXIF_Conn_fail = 1;
Connection = 1;
printf("MAXIF Connection error\n");
}
//////////END MAXIF/////////////////
///////////NCR 시작//////////////
//NSR 저장
//SR Mode 전환
write(NM_NSR, 0x10);
int init_NCR = read(NM_NCR);
// printf("init NCR : 0x%x\n",init_NCR);
//write NCR 0xaa
write(NM_NCR, 0xaa);
int temp_NCR = read(NM_NCR);
//printf("NCR : 0x%x\n", temp_NCR);
//NCR test
if(temp_NCR != 0xaa){
NCR_Conn_fail = 1;
Connection = 1;
printf("NCR Connection error\n");
}
//write NCR 0x55
write(NM_NCR, 0x55);
temp_NCR = read(NM_NCR);
//printf("NCR : 0x%x\n", temp_NCR);
//NCR test
if(temp_NCR != 0x55){
NCR_Conn_fail = 1;
Connection = 1;
printf("NCR Connection error\n");
}
///////////NCR 종료//////////////
/////////////////AIF
write(NM_AIF, 0xaaaa);
int temp_AIF = read(NM_AIF);
//printf("AIF : 0x%x\n", temp_AIF);
//AIF test
if(temp_AIF != 0xaaaa){
AIF_Conn_fail = 1;
Connection = 1;
printf("AIF Connection error\n");
}
//write AIF 0x55
write(NM_AIF, 0x5555);
temp_AIF = read(NM_AIF);
/// printf("AIF : 0x%x\n", temp_AIF);
//AIF test
if(temp_AIF != 0x5555){
AIF_Conn_fail = 1;
Connection = 1;
printf("AIF Connection error\n");
}
write(NM_NSR, 0x00);
if(Connection == 1)
printf("Connection Test Fail\n");
else
printf("Connection Test Pass\n");
}
void Memory_Test(void)
{
int ncount, old_ncnt;
printf("Memory Test Start \n");
printf("Data Save \n");
//1번째 학습 홀수 : 0x0a, 짝수 : 0x05
for(int i = 1; i <=MAXNEURONS; i=i+2){
//학습할 데이터
for(int j=0;j<NEURONSIZE;j=j+2){
array1[j] =0xa;
array1[j+1] =0x5;
array2[j] =0x5;
array2[j+1] =0xa;
}
//A 5 A 5....학습
ncount = learn(array1, NEURONSIZE, i); //input : data, neuronsize, cat, return : ncount
//5 A 5 A....학습
ncount = learn(array2, NEURONSIZE, i+1); //input : data, neuronsize, cat, return : ncount
//학습여부 판단
if(ncount == old_ncnt){ //ncount가 변화가 없으면
if(ncount <=576){
Learn1 = 1;
printf("NCOUNT : %d\n ", ncount);
error("\n Learn Fail NM500 #1\n");
}
else{
Learn2 = 1;
printf("NCOUNT : %d\n ", ncount);
error("\n Learn Fail NM500 #2\n");
}
}
//ncount가 증가하였을 경우
else{
old_ncnt = ncount; //old ncount 갱신
printf(".");
}
}
//학습 뉴런 갯수가 MAXNEURONS일 경우
if(ncount == 0xFFFF || ncount == 0x7FFF) //change
ncount = MAXNEURONS;
printf("\n");
//학습된 뉴런 갯수 출력
// printf("NCOUNT : %d ",ncount);
//end memory write
//NSR 백업
printf("Data Compare\n");
int temp_NSR = read(NM_NSR);
//write NSR-SR Mode
write(NM_NSR, 0x10);
write(NM_RSTCHAIN, 0);
int temp_data[NEURONSIZE];
for(int i = 1; i<=MAXNEURONS; i++){
printf(".");
//전체 뉴런 데이터 리드
for(int j = 0; j<NEURONSIZE; j++){
temp_data[j]=read(NM_COMP);
//fprintf(fp,"%d,", temp_data[j]);
//A 5 A 5 일 경우
if(i%2 == 1){
//학습한 데이터와 다를 경우
if(temp_data[j]!= array1[j]){
printf("\nNID : %d , %d byte Memory Error\n",i,j);
Memory_fail = 1;
}
}
//5 A 5 A 일 경우
else if( i%2 == 0){
//학습한 데이터와 다를 경우
if(temp_data[j]!= array2[j]){
printf("\nNID : %d , %d byte Memory Error\n",i,j);
Memory_fail = 1;
}
}
}
//다음 뉴런으로 변경
int cat = read(NM_CAT)& 0x7FFF;
//fprintf(fp,"\t%d\n", cat);
}
//노말모드로 복귀
write(NM_NSR, temp_NSR);
//초기화
forget();
////////////데이터 변경//////////////////
////////5 a 5 a learn///////////////////
printf("\nData Change\n");
for(int i = 1; i <=MAXNEURONS; i=i+2){
//memory array init
for(int j=0;j<NEURONSIZE;j=j+2){
array1[j] =0xa;
array1[j+1] =0x5;
array2[j] =0x5;
array2[j+1] =0xa;
}
ncount = learn(array2, NEURONSIZE, i); //input : data, neuronsize, cat, return : ncount
ncount = learn(array1, NEURONSIZE, i+1); //input : data, neuronsize, cat, return : ncount
if(ncount == old_ncnt){ //ncount가 변화가 없으면
if(ncount <=576){
Learn1 = 1;
printf("NCOUNT : %d\n",ncount);
error("\n Learn Fail NM500 #1\n");
}
else{
Learn2 = 1;
printf("NCOUNT : %d\n",ncount);
error("\n Learn Fail NM500 #2\n");
}
}
//ncount가 증가하였을 경우
else{
old_ncnt = ncount; //old ncount 갱신
printf(".");
}
}
//NCOUNT cheak
if(ncount == 0xFFFF || ncount == 0x7FFF) //change
ncount = MAXNEURONS;
//printf("NCOUNT : %d ",ncount);
//end memory write
//////////////////////////////////////////////////////////////
//fprintf(fp,"5 A\n");
//backup NSR
temp_NSR = read(NM_NSR);
//write NSR-SR Mode
write(NM_NSR, 0x10);
write(NM_RSTCHAIN, 0);
//compare memory(cheak)
printf("\nData Compare \n");
for(int i = 1; i<=MAXNEURONS; i++){
printf(".");
for(int j = 0; j<NEURONSIZE; j++){
temp_data[j]=read(NM_COMP);
//fprintf(fp,"%d,", temp_data[j]);
if(i%2 == 1){
if(temp_data[j]!= array2[j]){
printf("\nNID : %d , %d byte Memory Error\n",i,j);
Memory_fail = 1;
}
}
else if( i%2 == 0){
if(temp_data[j]!= array1[j]){
printf("\nNID : %d , %d byte Memory Error\n",i,j);
Memory_fail = 1;
}
}
}
int cat = read(NM_CAT)& 0x7FFF;
// fprintf(fp,"\t%d\n", cat);
}
//return Nomal Mode
write(NM_NSR, temp_NSR);
forget();
//fclose(fp);
//error("Momory test ok");
if(Memory_fail == 0)
printf("\nMemort Test Pass\n");
}
int data_learn(void)
{
int ncnt=0,old_ncnt=0; //ncount, old ncount
//number of neuron 576*2
for(int i=1;i<=MAXNEURONS;i++){
// ex
// 1. 0 1 0 1....
// 2. 0 2 0 2....
// 3. 0 3 0 3....
// .....
// 255. 0 255 0 255....
// 256. 1 0 1 0....
// 257. 1 1 1 1....
if(i%2 == 1){
for(int j =0;j<DATA_CNT;j=j+2){
vector[j] = i>>8; //upper bit save
vector[j+1] = i; //low bit save
}
for(int j =DATA_CNT;j<NEURONSIZE; j++){
vector[j] = array1[j]; //upper bit save
}
}
else if(i%2==0){
for(int j =0;j<DATA_CNT;j=j+2){
vector[j] = i>>8; //upper bit save
vector[j+1] = i; //low bit save
}
for(int j =DATA_CNT;j<NEURONSIZE; j++){
vector[j] = array2[j]; //upper bit save
}
}
//data learn
ncnt = learn(vector, NEURONSIZE, i); //input : data, neuronsize, cat, return : ncount
if(ncnt == 0xffff || ncnt == 0x7FFF) //change
ncnt = MAXNEURONS;
//pc.printf("ncount # %d\n",ncnt);
if(ncnt == old_ncnt){ //ncount가 변화가 없으면
if(ncnt <=576){
Learn1 = 1;
error("\n Learn Fail NM500 #1\n");
}
else{
Learn2 = 1;
error("\n Learn Fail NM500 #2\n");
}
}
//ncount가 증가하였을 경우
else
old_ncnt = ncnt; //old ncount 갱신
printf(".");
}
printf("\n");
// printf("NCOUNT : %d\n",ncnt);
//학습 완료 후 ncount가 MAXNEURONS보다 작을 경우
if(ncnt == MAXNEURONS/2)
return 1; //데이지체인 불량
else if( ncnt != MAXNEURONS)
error("NCOUNT Fail\n");
return 0; //정상 출력
}
int NeuronToSD()
{
char neurons[NEURONSIZE];
int aif=0;
fp = fopen("/sd/data.txt", "w");
if(fp == NULL)
error("Write SD Fail");
fflush(stdin);
//save NSR
int TempNSR = read(NM_NSR);
//read NCOUNT
int nm_cnt = read(NM_NCOUNT);
if(nm_cnt == 0xFFFF || nm_cnt == 0x7FFF) //change
nm_cnt = MAXNEURONS;
//printf("NCOUNT : %d\n", nm_cnt);
//write NSR-SR Mode
write(NM_NSR, 0x10);
//reset chain
write(NM_RSTCHAIN, 0);
//loop until max neruon
for(int cnt = 1; cnt<=nm_cnt; cnt++){
//read context
int context = read(NM_NCR);
//printf("context #%d\t,", context);
fprintf(fp,"%d\t", context);
//GCR register fail
if(context != 5){
if(cnt < 577){ //neuron1 fail
Gcr1=1;
printf("\nNID # %d, GCR # %d \n",cnt,context);
}
else{ //neruon2 fail
Gcr2=1;
printf("\nNID # %d, GCR # %d \n",cnt,context);
}
}
char temp_neuron[NEURONSIZE];
// for(int j =0;j<NEURONSIZE;j=j+2){
// temp_neuron[j] = cnt>>8; //upper bit save
// temp_neuron[j+1] = cnt; //low bit save
// }
if(cnt%2 == 1){
for(int j =0;j<DATA_CNT;j=j+2){
temp_neuron[j] = cnt>>8; //upper bit save
temp_neuron[j+1] = cnt; //low bit save
}
for(int j =DATA_CNT;j<NEURONSIZE; j++){
temp_neuron[j] = array1[j]; //upper bit save
}
}
else if(cnt%2 == 0){
for(int j =0;j<DATA_CNT;j=j+2){
temp_neuron[j] = cnt>>8; //upper bit save
temp_neuron[j+1] = cnt; //low bit save
}
for(int j =DATA_CNT;j<NEURONSIZE; j++){
temp_neuron[j] = array2[j]; //upper bit save
}
}
//printf("Neruon Data : ");
//read Neuron data
for (int j=0; j<NEURONSIZE; j++){
//read COMP
neurons[j]=read(NM_COMP);
fprintf(fp,"%d,", neurons[j]);
//printf("%d,", neurons[j]);
if(temp_neuron[j]!= neurons[j]){
if(j<MAXNEURONS/2){
printf("NID # %d Memory Fail\n", cnt);
Memory1 = 1;
}
else{
printf("NID # %d Memory Fail\n", cnt);
Memory2 = 1;
}
printf("# %d : temp %d, neruon %d\n",j, temp_neuron[j],neurons[j]);
}
}
//read AIF
aif=read(NM_AIF);
fprintf(fp,"\t%d\t", aif);
//printf("AIF : %d,\t", aif);
//aif register fail
if(aif != 5){
if(cnt <= 576){ //neuron1 fail
Aif1=1;
printf("\nNID # %d, AIF # %d \n",cnt,aif);
}
else{ //neruon2 fail
Aif2=1;
printf("\nNID # %d, AIF # %d \n",cnt,aif);
}
}
//raed minif
int minif=read(NM_MINIF);
//printf("MINIF : %d,\t", minif);
fprintf(fp,"%d\t", minif);
//minif register fail
if(minif != 3){
if(cnt <= 576){ //neuron1 fail
Minif1 = 1;
printf("\nNID # %d, MINIF # %d \n",cnt,minif);
}
else{ //neruon2 fail
Minif2 = 1;
printf("\nNID # %d, MINIF # %d \n",cnt,minif);
}
}
//read cat
int cat = read(NM_CAT) & 0x7FFF;
fprintf(fp,"%d\t", cat);
fprintf(fp,"\n");
//printf("****CAT : %d\n", cat);
//reset chain test
// if(cnt > 2 && cat == 1)
// CMN_RC = 1;
//cat test
if(cnt != cat){
printf("cnt : %d , cat : %d \n", cnt, cat);
if(cnt <= 576){
Cat1 = 1;
printf("\n NM500 #1 Cat Fail # %d\n", cnt);
}
else {
Cat2 = 1;
printf("\n NM500 #2 Cat Fail # %d\n", cnt);
}
}
printf(".");
}
printf("\n");
fclose(fp);
write(NM_NSR, TempNSR); // set the NN back to its calling status
return read(NM_NCOUNT);
}
int SDToNeurons()
{
int context,aif,minif,cat;
char neurons[NEURONSIZE];
fp = fopen("/sd/data.txt", "r");
if(fp == NULL)
error("Read SD Fail");
//save NSR
int TempNSR = read(NM_NSR);
//write NSR-SR Mode
write(NM_NSR, 0x10);
//reset chain
write(NM_RSTCHAIN, 0);
//SD data read -> Neurons
for(int i=1;i<=MAXNEURONS;i++){
//read context
fscanf(fp,"%d", &context);
// printf("context # %d ", context);
write(NM_GCR,context);
//read comp
for (int j=0; j<NEURONSIZE; j++){
//read COMP
fscanf(fp,"%d,", &neurons[j]);
// printf("%d\t,", neurons[j]);
write(NM_COMP,neurons[j]);
}
fscanf(fp,"\t%d\t", &aif);
// printf("AIF # %d \t", aif);
write(NM_AIF,aif);
fscanf(fp,"%d\t", &minif);
// printf("MINIF # %d", minif);
write(NM_MINIF,minif);
fscanf(fp,"%d\t", &cat);
// printf("CAT # %d \n", cat);
write(NM_CAT,cat);
printf(".");
}
printf("\n");
fclose(fp);
write(NM_NSR, TempNSR); // set the NN back to its calling status
return NCOUNT();
}
void NSR_Test(void)
{
//KNN Mode setting
setKNN();
//read KNN Register
int nsr = read(NM_NSR) & 0x20;
if(nsr != 32)
CMN_Nsr = 1; //fail
//RBF Mode setting
setRBF();
nsr = read(NM_NSR) & 0x20;
if(nsr != 0)
CMN_Nsr = 1; //fail
int temp_nsr = read(NM_NSR);
//SR Mode test
write(NM_NSR, 0x10);
nsr = read(NM_NSR) & 0x10;
if(nsr != 16)
CMN_Nsr = 1;
//Nomal Mode Test
write(NM_NSR, temp_nsr);
nsr = read(NM_NSR) & 0x10;
if(nsr != 0)
CMN_Nsr = 1;
}
void data_classify(void)
{
int distance, cat, nid;
//number of neuron 1156
for(int i=1;i<=MAXNEURONS;i++){
if(i%2 == 1){
for(int j =0;j<DATA_CNT;j=j+2){
vector[j] = i>>8; //upper bit save
vector[j+1] = i; //low bit save
}
for(int j =DATA_CNT;j<NEURONSIZE; j++){
vector[j] = array1[j]; //upper bit save
}
}
else if(i%2==0){
for(int j =0;j<DATA_CNT;j=j+2){
vector[j] = i>>8; //upper bit save
vector[j+1] = i; //low bit save
}
for(int j =DATA_CNT;j<NEURONSIZE; j++){
vector[j] = array2[j]; //upper bit save
}
}
//input : data, data length output : distance, category, Neuron ID return 인식된 데이터 갯수
int nsr = classify(vector, NEURONSIZE, &distance, &cat, &nid);
id_fail = nsr & 0x70;
if(id_fail == 0)
nsr_fail = 1;
printf(".");
// printf(" neuron# %d \t", nid);
// printf(" distance = %d,\t ", distance);
// printf(" cat = %d\n", cat);
//nid test
//cat register pass AND (nid,cat diff)
if((nid!=cat) && (Cat1==0 && Cat2==0)){
if(nid < 576){
Nid1 = 1;
printf("\nNID Register Fail # %d\n",nid);
}
else{
Nid2 = 1;
printf("\nNID Register Fail # %d\n",nid);
}
}
if(distance != 0){
if(nid < 576){
Dist1 = 1;
printf("\nDistance Register Fail # %d, Distance # %d\n",nid,distance);
}
else{
Dist2 = 1;
printf("\nDistance Register Fail # %d, Distance # %d\n",nid,distance);
}
}
}
printf("\n");
}