void NF_Page_Read(unsigned long addr, unsigned char *buff, int size) { int i, len; // 选中NF select_chip(); // 清除RnB clear_RnB(); // 发送0x00命令 send_cmd(0x00); // 发送2个列地址 send_addr(0x00); send_addr(0x00); // 发送3个行地址 send_addr(addr & 0xFF); send_addr((addr >> 8) & (0xFF)); send_addr((addr >> 16) & (0xFF)); // 发送0x30命令 send_cmd(0x30); // 等待RnB信号 wait_RnB(); /* 判断出一个合适的size */ if(size > PAGE_SIZE) len = size > PAGE_SIZE*4 ? PAGE_SIZE*4 : size; else if(size < PAGE_SIZE) len = size; else len = PAGE_SIZE; // len = size > PAGE_SIZE ? size : PAGE_SIZE; // if(len > PAGE_SIZE*4) // len = PAGE_SIZE*4; // 读取数据 for(i=0; i < len; i++) { *buff++ = NFDATA; } //取消选中 delete_chip(); }
void reset() { // 选中NandFlash select_chip(); // 清除RnB(NF忙信号) clear_RnB(); // 发送0xFF信号 send_cmd(0xFF); // 等待RnB wait_RnB(); // 取消选中 delete_chip(); }
void serprog_handle_command(unsigned char command) { static uint8_t i; /* Loop */ static uint8_t l; /* Length */ static uint32_t slen; /* SPIOP write len */ static uint32_t rlen; /* SPIOP read len */ static uint32_t freq_req; LED0=0; switch(command) { case S_CMD_NOP: usb_putc(S_ACK); break; case S_CMD_Q_IFACE: usb_putc(S_ACK); /* little endian multibyte value to complete to 16bit */ usb_putc(S_IFACE_VERSION); usb_putc(0); break; case S_CMD_Q_CMDMAP: usb_putc(S_ACK); /* little endian */ usb_putu32(S_CMD_MAP); for(i = 0; i < 32 - sizeof(uint32_t); i++) usb_putc(0); break; case S_CMD_Q_PGMNAME: usb_putc(S_ACK); l = 0; while(S_PGM_NAME[l]) { usb_putc(S_PGM_NAME[l]); l ++; } for(i = l; i < 16; i++) usb_putc(0); break; case S_CMD_Q_SERBUF: usb_putc(S_ACK); /* Pretend to be 64K (0xffff) */ usb_putc(0xff); usb_putc(0xff); break; case S_CMD_Q_BUSTYPE: // TODO: LPC / FWH IO support via PP-Mode usb_putc(S_ACK); usb_putc(S_SUPPORTED_BUS); break; case S_CMD_Q_CHIPSIZE: break; case S_CMD_Q_OPBUF: // TODO: opbuf function 0 break; case S_CMD_Q_WRNMAXLEN: break; case S_CMD_R_BYTE: break; case S_CMD_R_NBYTES: break; case S_CMD_O_INIT: break; case S_CMD_O_WRITEB: // TODO: opbuf function 1 break; case S_CMD_O_WRITEN: // TODO: opbuf function 2 break; case S_CMD_O_DELAY: // TODO: opbuf function 3 break; case S_CMD_O_EXEC: // TODO: opbuf function 4 break; case S_CMD_SYNCNOP: usb_putc(S_NAK); usb_putc(S_ACK); break; case S_CMD_Q_RDNMAXLEN: // TODO break; case S_CMD_S_BUSTYPE: /* We do not have multiplexed bus interfaces, * so simply ack on supported types, no setup needed. */ if((usb_getc() | S_SUPPORTED_BUS) == S_SUPPORTED_BUS) usb_putc(S_ACK); else usb_putc(S_NAK); break; case S_CMD_O_SPIOP: slen = usb_getu24(); rlen = usb_getu24(); select_chip(); /* TODO: handle errors with S_NAK */ if(slen) spi_bulk_write(slen); usb_putc(S_ACK); if(rlen) spi_bulk_read(rlen); unselect_chip(); break; case S_CMD_S_SPI_FREQ: freq_req = usb_getu32(); if(freq_req == 0) usb_putc(S_NAK); else { usb_putc(S_ACK); usb_putu32(spi_conf(freq_req)); } break; default: break; // TODO: Debug malformed command } LED0=1; }
int io_read (resmgr_context_t *ctp, io_read_t *msg, RESMGR_OCB_T *ocb) { int nleft; int nbytes; int nparts; int status; uint32_t chip; char lbuff[64]; uint32_t cval; if ((status = iofunc_read_verify(ctp, msg, ocb, NULL)) != EOK) return(status); if ((msg->i.xtype & _IO_XTYPE_NONE) != _IO_XTYPE_NONE) return (ENOSYS); /* * On all reads, calculate how many * bytes we can return to the client * based upon the number of bytes available (nleft) * and the client's buffer size */ nleft = ocb->attr->nbytes - ocb->offset; nbytes = min(msg->i.nbytes, nleft); cval = *(uint32_t *)ics660->regs.control; fprintf(stderr,"io_read - cval %d\n",cval); sprintf(lbuff,"%x",cval); for( chip=1; chip<=4; chip++){ select_chip(ics660->mod_control_reg,chip); printf("MAIN PRINT_REGISTER\n"); print_registers(ics660->dc60m_regs); } select_chip(ics660->mod_control_reg,(uint32_t)0x0); if (nbytes > 0){ /* set up the return data IOV */ //SETIOV( ctp->iov, buffer + ocb->offset, nbytes ); SETIOV( ctp->iov, lbuff + ocb->offset, nbytes ); /* set up the number of bytes (returned by client's read()) */ _IO_SET_READ_NBYTES(ctp, nbytes); /* * advance the offset by the number of bytes * returned to the client. */ ocb->offset += nbytes; nparts = 1; } else { /* * they've asked for zero bytres or they've already * read everything */ _IO_SET_READ_NBYTES(ctp,0); nparts = 0; } /* mark the access time as invalid (we just accessed it) */ if (msg->i.nbytes > 0) ocb->attr->flags |= IOFUNC_ATTR_ATIME; return (_RESMGR_NPARTS(nparts)); }
int io_devctl (resmgr_context_t *ctp, io_devctl_t *msg, RESMGR_OCB_T *ocb){ int nbytes, status, previous; uint32_t chip, page, reg; uint32_t value, temp, command, offset; uint32_t sequencer_base = 0x00100000; struct ICS660_FILTER filter_str; struct ICS660_FREQ freq_str; struct ICS660_PHASE phase_str; struct ICS660_sequencer seq_data; union { data_t data; uint32_t data32; int int_data; struct ICS660_FILTER filter_str; struct ICS660_FREQ freq_str; struct ICS660_PHASE phase_str; struct dc60m_p_val dc60m_p; struct dc60m_pg_reg pg_reg; struct ICS660_sequencer seq_data; } *rx_data; pdebug("IO_DEVCTL - entry -\n"); if((status = iofunc_devctl_default(ctp, msg, ocb)) != _RESMGR_DEFAULT) return(status); rx_data = _DEVCTL_DATA(msg->i); //pdebug("IO_DEVCTL - rx_data %d filter_str %d\n",rx_data,sizeof(rx_data->filter_str)); //pdebug("IO_DEVCTL - msg %d msg.i %d \n",msg,msg->i); command = get_device_command(msg->i.dcmd); pdebug("IO_DEVCTL - command %x %x\n",msg->i.dcmd,command); switch(msg->i.dcmd){ case ICS660_BOARD_RESET: pdebug("IO_DEVCTL - BOARD_RESET %x\n",value); *(unsigned int*)(ics660->regs.board_reset) = RESET_VALUE; break; case ICS660_CLEAR_IMASK: pdebug("IO_DEVCTL - CLEAR_IMASK %x\n",value); *(unsigned int*)(ics660->regs.interrupt_mask) = (uint32_t)IMASK_VALUE; break; case ICS660_TRIGGER_SOURCE: value = rx_data->data32; pdebug("IO_DEVCTL - TRIGGER_SOURCE %x\n",value); temp = *(uint32_t *)ics660->regs.control & ~TRIGGER_SOURCE; *(uint32_t *)ics660->regs.control = temp | value; break; case ICS660_CLOCK_SELECT: value = rx_data->data32; temp = *(uint32_t *)ics660->regs.control & ~CLOCK_SELECT; value = (value << 1) & CLOCK_SELECT; pdebug("IO_DEVCTL - CLOCK_SELECT %x\n",value); *(uint32_t *)ics660->regs.control = temp | value; break; case ICS660_MODE: value = rx_data->data32; temp = *(uint32_t *)ics660->regs.control & ~MODE; value = value & MODE; pdebug("IO_DEVCTL - ICS660_MODE %x\n",value); *(uint32_t *)ics660->regs.control = temp | value; break; case ICS660_UPCONVERTER_SELECT: value = rx_data->data32; temp = *(uint32_t *)ics660->regs.control & ~UPCONVERTER_SELECT; value = (value << 4) & UPCONVERTER_SELECT; pdebug("IO_DEVCTL - UPCONVERTER_SELECT %x\n",value); *(uint32_t *)ics660->regs.control = temp | value; break; case ICS660_DATA_SOURCE: value = rx_data->data32; temp = *(uint32_t *)ics660->regs.control & ~DATA_SOURCE; value = (value << 5) & DATA_SOURCE; pdebug("IO_DEVCTL - DATA_SOURCE %x\n",value); *(uint32_t *)ics660->regs.control = temp | value; break; case ICS660_FPDP_CLOCK_SEL: value = rx_data->data32; temp = *(uint32_t *)ics660->regs.control & ~FPDP_CLOCK_SEL; value = (value << 6) & FPDP_CLOCK_SEL; pdebug("IO_DEVCTL - FPDP_CLOCK_SEL %x\n",value); *(uint32_t *)ics660->regs.control = temp | value; break; case ICS660_FPDP_TERM: value = rx_data->data32; temp = *(uint32_t *)ics660->regs.control & ~FPDP_TERM; value = (value << 7) & FPDP_TERM; pdebug("IO_DEVCTL - FPDP_TERM %x\n",value); *(uint32_t *)ics660->regs.control = temp | value; break; case ICS660_SYNC_MASTER: value = rx_data->data32; temp = *(uint32_t *)ics660->regs.control & ~SYNC_MASTER; value = (value << 8) & SYNC_MASTER; pdebug("IO_DEVCTL - SYNC_MASTER %x\n",value); *(uint32_t *)ics660->regs.control = temp | value; break; case ICS660_SYNC_TERM: value = rx_data->data32; temp = *(uint32_t *)ics660->regs.control & ~SYNC_TERM; value = (value << 9) & SYNC_TERM; pdebug("IO_DEVCTL - SYNC_TERM %x\n",value); *(uint32_t *)ics660->regs.control = temp | value; break; case ICS660_DAC_ENABLE: value = rx_data->data32; temp = *(uint32_t *)ics660->regs.control & ~DAC_ENABLE; value = (value << 10) & DAC_ENABLE; pdebug("IO_DEVCTL - DAC_ENABLE %x\n",value); *(uint32_t *)ics660->regs.control = temp | value; break; case ICS660_DAC_RESET: value = rx_data->data32; pdebug("IO_DEVCTL - DAC_RESET %x\n",value); *(uint32_t *)ics660->regs.dac_reset = value; break; case ICS660_TRIGGER: value = rx_data->data32; temp = *(uint32_t *)ics660->regs.control & ~TRIGGER; value = (value << 11) & TRIGGER; pdebug("IO_DEVCTL - TRIGGER %x\n",value); *(uint32_t *)ics660->regs.control = temp | value; break; case ICS660_BANK_WIDTH: value = rx_data->int_data; pdebug("IO_DEVCTL - BANK_WIDTH %d\n",value); *(uint32_t *)ics660->regs.bank_width = (uint32_t) value; break; case ICS660_BANK_LENGTH: value = rx_data->int_data; pdebug("IO_DEVCTL - BANK_LENGTH %d\n",value); *(uint32_t *)ics660->regs.bank_length = (uint32_t) value; break; case ICS660_PERSISTENCE_REG: value = rx_data->int_data; pdebug("IO_DEVCTL - PERSISTENCE %d\n",value); *(uint32_t *)ics660->regs.persistence = (uint32_t) value; break; case ICS660_TRANS_LENGTH: value = rx_data->int_data; pdebug("IO_DEVCTL - TRANSMIT_LENGTH: %d\n",value); *(uint32_t *)ics660->regs.trans_length = (uint32_t) value; break; case ICS660_WRITE_SEQUENCER: pdebug("IO_DEVCTL - WRITE_SEQUENCER offset: %x value: %x\n",(uint32_t)rx_data->seq_data.offset,(uint32_t)rx_data->seq_data.value ); seq_data.offset = rx_data->seq_data.offset; seq_data.value = rx_data->seq_data.value; *(uint32_t *)(ics660->mem0 + sequencer_base + (uint32_t)seq_data.offset) = (uint32_t)seq_data.value; break; case ICS660_LOAD_FILTER: pdebug("_ICS660_DRV: LOAD_FILTER\n"); filter_str.chip = rx_data->filter_str.chip; filter_str.channel = rx_data->filter_str.channel; filter_str.f_corner = rx_data->filter_str.f_corner; filter_str.state_time = rx_data->filter_str.state_time; pdebug("_ICS660_DRV: LOAD_FILTER - \n CHIP %d\n CHANNEL %d\n F_CORNER %d\n STATE_TIME %f\n",filter_str.chip,filter_str.channel,filter_str.f_corner,filter_str.state_time); select_chip(ics660->mod_control_reg,filter_str.chip); load_filter_taps(ics660->dc60m_regs,filter_str.channel,filter_str.f_corner, filter_str.state_time); select_chip(ics660->mod_control_reg,0); break; case ICS660_LOAD_FREQUENCY: pdebug("_ICS660_DRV: LOAD_FREQUENCY\n"); freq_str.chip = rx_data->freq_str.chip; freq_str.channel = rx_data->freq_str.channel; freq_str.freq = rx_data->freq_str.freq; select_chip(ics660->mod_control_reg,freq_str.chip); pdebug("_ICS660_DRV: LOAD_FREQ - \n CHIP %d\n CHANNEL %d\n FREQ %f\n",freq_str.chip,freq_str.channel,freq_str.freq); load_frequency(ics660->dc60m_regs,freq_str.channel,freq_str.freq); break; case ICS660_LOAD_PHASE: pdebug("_ICS660_DRV: LOAD_PHASE\n"); phase_str.chip = rx_data->phase_str.chip; phase_str.channel = rx_data->phase_str.channel; phase_str.phase = rx_data->phase_str.phase; select_chip(ics660->mod_control_reg,phase_str.chip); load_phase(ics660->dc60m_regs,phase_str.channel,phase_str.phase); break; case ICS660_SET_DC_READY: pdebug("IO_DEVCTL - SET_DC_READY %x\n",value); set_dc_ready(ics660->mod_control_reg); break; case ICS660_RELEASE_RESETS: pdebug("IO_DEVCTL - RELEASE_RESETS %x\n",value); release_dc60m_resets(ics660->mod_control_reg,ics660->dc60m_regs); break; case ICS660_SET_CHIP: chip = rx_data->data32; select_chip(ics660->mod_control_reg,chip); break; case ICS660_SET_PAGE: chip = rx_data->data32; select_chip(ics660->mod_control_reg,chip); break; case ICS660_MODULE_CONTROL_REG: value = rx_data->data32; pdebug("IO_DEVCTL - MODULE_CONTROL_REG %d\n",value); *(uint32_t *)ics660->mod_control_reg = (uint32_t)value; break; case ICS660_DC60M_RESET: chip = rx_data->dc60m_p.chip; value = rx_data->dc60m_p.value; select_chip(ics660->mod_control_reg,chip); pdebug("IO_DEVCTL - DC60M_RESET - chip %d value %x\n",chip,value); *(uint32_t *)ics660->dc60m_regs.reset = (uint32_t) value; break; case ICS660_MISCELANEOUS: chip = rx_data->dc60m_p.chip; value = rx_data->dc60m_p.value; select_chip(ics660->mod_control_reg,chip); pdebug("IO_DEVCTL - MISCELANEOUS - chip %d value %x\n",chip,value); *(uint32_t *)ics660->dc60m_regs.miscelaneous = (uint32_t)value; break; case ICS660_SYNC_MODE: chip = rx_data->dc60m_p.chip; value = rx_data->dc60m_p.value; select_chip(ics660->mod_control_reg,chip); pdebug("IO_DEVCTL - SYNC_MODE - chip %d value %x\n",chip,value); *(uint32_t *)ics660->dc60m_regs.sync_mode = (uint32_t) value; break; case ICS660_INTERPOLATION_MODE: chip = rx_data->dc60m_p.chip; value = rx_data->dc60m_p.value; select_chip(ics660->mod_control_reg,chip); pdebug("IO_DEVCTL - INTERPOLATION_MODE - chip %d value %x\n",chip,value); *(uint32_t *)ics660->dc60m_regs.interpolation_mode = (uint32_t) value; break; case ICS660_CHANNEL_A_SYNC: chip = rx_data->dc60m_p.chip; value = rx_data->dc60m_p.value; select_chip(ics660->mod_control_reg,chip); pdebug("IO_DEVCTL - CHANNEL_A_SYNC - chip %d value %x\n",chip,value); *(uint32_t *)ics660->dc60m_regs.channel_a_sync = (uint32_t) value; break; case ICS660_CHANNEL_B_SYNC: chip = rx_data->dc60m_p.chip; value = rx_data->dc60m_p.value; select_chip(ics660->mod_control_reg,chip); pdebug("IO_DEVCTL - CHANNEL_B_SYNC - chip %d value %x\n",chip,value); *(uint32_t *)ics660->dc60m_regs.channel_b_sync = (uint32_t) value; break; case ICS660_CHANNEL_C_SYNC: chip = rx_data->dc60m_p.chip; value = rx_data->dc60m_p.value; select_chip(ics660->mod_control_reg,chip); pdebug("IO_DEVCTL - CHANNEL_C_SYNC - chip %d value %x\n",chip,value); *(uint32_t *)ics660->dc60m_regs.channel_c_sync = (uint32_t) value; break; case ICS660_CHANNEL_D_SYNC: chip = rx_data->dc60m_p.chip; value = rx_data->dc60m_p.value; select_chip(ics660->mod_control_reg,chip); pdebug("IO_DEVCTL - CHANNEL_D_SYNC - chip %d value %x\n",chip,value); *(uint32_t *)ics660->dc60m_regs.channel_d_sync = (uint32_t) value; break; case ICS660_CHANNEL_FLUSH_MODE: chip = rx_data->dc60m_p.chip; value = rx_data->dc60m_p.value; select_chip(ics660->mod_control_reg,chip); pdebug("IO_DEVCTL - CHANNEL_FLUSH_MODE - chip %d value %x\n",chip,value); *(uint32_t *)ics660->dc60m_regs.channel_flush_mode = (uint32_t) value; break; case ICS660_INTERPOLATION_GAIN: chip = rx_data->dc60m_p.chip; value = rx_data->dc60m_p.value; select_chip(ics660->mod_control_reg,chip); pdebug("IO_DEVCTL - INTERPOLATION_GAIN - chip %d value %x\n",chip,value); *(uint32_t *)ics660->dc60m_regs.interpolation_gain = (uint32_t) value; break; case ICS660_INTERPOLATION_BYTE0: chip = rx_data->dc60m_p.chip; value = rx_data->dc60m_p.value; select_chip(ics660->mod_control_reg,chip); pdebug("IO_DEVCTL - INTERPOLATION_BYTE0 - chip %d value %x\n",chip,value); *(uint32_t *)ics660->dc60m_regs.interpolation_byte0 = (uint32_t) value; break; case ICS660_INTERPOLATION_BYTE1: chip = rx_data->dc60m_p.chip; value = rx_data->dc60m_p.value; select_chip(ics660->mod_control_reg,chip); pdebug("IO_DEVCTL - INTERPOLATION_BYTE1 - chip %d value %x\n",chip,value); *(uint32_t *)ics660->dc60m_regs.interpolation_byte1 = (uint32_t) value; break; case ICS660_COUNTER_BYTE0: chip = rx_data->dc60m_p.chip; value = rx_data->dc60m_p.value; select_chip(ics660->mod_control_reg,chip); pdebug("IO_DEVCTL - COUNTER_BYTE0 - chip %d value %x\n",chip,value); *(uint32_t *)ics660->dc60m_regs.counter_byte0 = (uint32_t) value; break; case ICS660_COUNTER_BYTE1: chip = rx_data->dc60m_p.chip; value = rx_data->dc60m_p.value; select_chip(ics660->mod_control_reg,chip); pdebug("IO_DEVCTL - COUNTER_BYTE1 - chip %d value %x\n",chip,value); *(uint32_t *)ics660->dc60m_regs.counter_byte1 = (uint32_t) value; break; case ICS660_DC_STAT: chip = rx_data->dc60m_p.chip; value = rx_data->dc60m_p.value; select_chip(ics660->mod_control_reg,chip); pdebug("IO_DEVCTL - STAT - chip %d value %x\n",chip,value); *(uint32_t *)ics660->dc60m_regs.stat = (uint32_t) value; break; case ICS660_SET_PAGE_REG: page = rx_data->pg_reg.page; chip = rx_data->pg_reg.chip; reg = rx_data->pg_reg.reg; value = rx_data->pg_reg.value; select_chip(ics660->mod_control_reg,chip); pdebug("IO_DEVCTL - PAGE_REG - chip %d page %d reg %d value %x\n",chip,page,reg,value); *(uint32_t *)ics660->dc60m_regs.page = page; *(uint32_t *)ics660->dc60m_regs.input_registers[(int)reg] = (uint32_t) value; break; default: pdebug("IO_DEVCTL - ERROR - no matching case %d\n",value); return(ENOSYS); } memset(&msg->o, 0, sizeof(msg->o)); msg->o.ret_val = status; msg->o.nbytes = nbytes; return(_RESMGR_PTR(ctp, &msg->o, sizeof(msg->o)+nbytes)); }
void main(void) { /* Configure the oscillator for the device */ ConfigureOscillator(); /* Initialize I/O and Peripherals for application */ InitApp(); select_chip(1); // Select the ADT7320 SSPBUF = 0b00001000; // Command byte indicating a write buf_wait(); SSPBUF = 0b00000000; // Write to the ADT7320 config register buf_wait(); select_chip(2); // Select the AD7793 ADC SSPBUF = 0b00001000; // Command byte indicating a write to the buf_wait(); // mode register SSPBUF = 0b00000000; // First 8 bits of the 16 bit mode register buf_wait(); SSPBUF = 0b11000001; // Second 8 bits of the mode register buf_wait(); select_chip(1); SSPBUF = 0b01010000; // Command byte to read temperature buf_wait(); int junc_bin = SSPBUF/1000; float junc_temp = 25; int loop_counter = 0; while(1) { PORTCbits.RC6 = 0b1; PORTCbits.RC7 = 0b1; PORTBbits.RB5 = 0b1; PORTBbits.RB4 = 0b1; PORTBbits.RB3 = 0b1; PORTBbits.RB2 = 0b1; PORTBbits.RB1 = 0b1; PORTBbits.RB0 = 0b1; PORTA = 0b11110111; for (int thermo_sel = 1; thermo_sel < 3; thermo_sel++) { select_chip(2); SSPBUF = 0b00010000; // Command byte indicating a write to the buf_wait(); // config register for the thermocouple SSPBUF = 0b01000110; // First 8 bits of the 16 bit config register buf_wait(); // for the thermocouple switch (thermo_sel) { case 1: SSPBUF = 0b10010000; // Second 8 bits for the first thermo buf_wait(); break; case 2: SSPBUF = 0b10010001; // Second 8 bits for the second thermo buf_wait(); break; } int not_ready = 1; while (not_ready == 1) { SSPBUF = 0b01000000; // Command byte to read status buf_wait(); not_ready = SSPBUF/10000000; } SSPBUF = 0b01011000; // Command byte to read from first thermo buf_wait(); float thermo_v = 0; for (int i=0; i<3; i++) { //thermo_v += (binary_decimal(SSPBUF) * (16 - i * 8)); } junc_temp = (binary_decimal(junc_bin))/16.0; // if (junc_temp/1000000000000) {junc_temp = (binary_decimal(junc_bin) - 8192)/16.0;} float tc = temp_voltage(junc_temp) + thermo_v; seven_segment(voltage_temp(tc), thermo_sel); } loop_counter++; if (loop_counter > 100) { loop_counter = 0; select_chip(1); SSPBUF = 0b01010000; // Command byte to read temperature buf_wait(); junc_bin = SSPBUF; } char* str = display_number(216.98); char strval[5]; for (int i=0; i<6; i++) {strval[i] = *(str+i);} char digit = strval[0]; int val = 5; switch (digit) { case 0x30: val = 0; break; case 0x31: val = 1; break; case 0x32: val = 2; break; } int result = val; /* TODO <INSERT USER APPLICATION CODE HERE> */ } }