static void export_cb(void *st, errval_t err, iref_t iref) { size_t size = 0; char *service_name = NULL; char *driver_name = (char *) st; if (err_is_fail(err)) { USER_PANIC_ERR(err, "Exporting basic interface failed.\n"); } // build service name as driver_name.SERVICE_SUFFIX size = snprintf(NULL, 0, "%s.%s", driver_name, SERVICE_SUFFIX); service_name = (char *) malloc(size + 1); if (service_name == NULL) { USER_PANIC("Error allocating memory."); } snprintf(service_name, size + 1, "%s.%s", driver_name, SERVICE_SUFFIX); SERIAL_DEBUG("About to register basic interface '%s' at nameservice.\n", service_name); // register basic serial driver service at nameservice err = nameservice_register(service_name, iref); if (err_is_fail(err)) { USER_PANIC_ERR(err, "Registering basic interface at " "nameserver failed."); } free(service_name); }
// Read data from buffer (byte per byte) Uint16 serial_getRxBufferedWord(){ SERIAL_DEBUG(); // TODO: check if it is needed while (SciaRegs.SCIRXST.bit.RXRDY) ; return SciaRegs.SCIRXBUF.all; }
static void associate_stdin_handler(struct serial_binding *b) { SERIAL_DEBUG("associate_stdin called on basic interface\n"); terminal = b; set_new_input_consumer(basic_serial_input); // try to send something, if we have it ready if (inbuf[ninbuf].buf != NULL) { tx_handler(b); } }
void start_basic_service(char *driver_name) { errval_t err; err = serial_export(driver_name, export_cb, connect_cb, get_default_waitset(), IDC_EXPORT_FLAGS_DEFAULT); if (err_is_fail(err)) { USER_PANIC_ERR(err, "Preparing basic interface for export failed."); } SERIAL_DEBUG("Exporting basic interface.\n"); }
// Transmit variable data based on passed size void serial_transmitData(Uint16 * data, Uint16 size){ static unsigned short i = 0; SERIAL_DEBUG(); for (i = 0; i < size; i++){ SciaRegs.SCITXBUF= data[i]; if(i%4 == 0){ while (SciaRegs.SCICTL2.bit.TXEMPTY != true) ; } } // If you want to wait until the TX buffer is empty, uncomment line below // while (SciaRegs.SCICTL2.bit.TXEMPTY != true) ; }
static errval_t connect_cb(void *st, struct serial_binding *b) { SERIAL_DEBUG("Client connected to basic interface.\n"); b->rx_vtbl = serial_rx_vtbl; terminal = b; set_new_input_consumer(basic_serial_input); // try to send something, if we have it ready if (inbuf[ninbuf].buf != NULL) { tx_handler(b); } return SYS_ERR_OK; }
// Construct the Serial Module Serial construct_Serial(){ Serial serial; serial.clear = serial_clear; serial.rxBufferStatus = serial_rxBufferStatus; serial.setSerialRxEnabled = serial_setSerialRxEnabled; serial.setSerialTxEnabled = serial_setSerialTxEnabled; serial.init = serial_init; serial.transmitData = serial_transmitData; serial.getRxBufferedWord = serial_getRxBufferedWord; serial.getRxError = serial_getRxError; serial.fifoWaitBuffer = 0; SERIAL_DEBUG(); return serial; }
// Clear flags of overflow void serial_clear(){ static unsigned short i, destroyFifo; SERIAL_DEBUG(); // Reset Serial in case of error if(SciaRegs.SCIRXST.bit.RXERROR == true){ SciaRegs.SCICTL1.bit.SWRESET=0; } // Clears FIFO buffer (if there is any data) for (i = SciaRegs.SCIFFRX.bit.RXFFST; i > 0; i--) destroyFifo = SciaRegs.SCIRXBUF.all; // Reset FIFO SciaRegs.SCIFFRX.bit.RXFIFORESET=1; SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1; SciaRegs.SCICTL1.bit.SWRESET=1; }
// Initialize Serial (actually SCIA) void serial_init(Serial *self){ Uint32 baudrate; // START: GOT FROM InitScia() FUNCTION (TEXAS FILES) //////////////////////////////////////// EALLOW; /* Enable internal pull-up for the selected pins */ // Pull-ups can be enabled or disabled disabled by the user. // This will enable the pullups for the specified pins. GpioCtrlRegs.GPAPUD.bit.GPIO28 = 0; // Enable pull-up for GPIO28 (SCIRXDA) GpioCtrlRegs.GPAPUD.bit.GPIO29 = 0; // Enable pull-up for GPIO29 (SCITXDA) /* Set qualification for selected pins to asynch only */ // Inputs are synchronized to SYSCLKOUT by default. // This will select asynch (no qualification) for the selected pins. GpioCtrlRegs.GPAQSEL2.bit.GPIO28 = 3; // Asynch input GPIO28 (SCIRXDA) /* Configure SCI-A pins using GPIO regs*/ // This specifies which of the possible GPIO pins will be SCI functional pins. GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 1; // Configure GPIO28 for SCIRXDA operation GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 1; // Configure GPIO29 for SCITXDA operation EDIS; // END: GOT FROM InitScia() FUNCTION (TEXAS FILES) //////////////////////////////////////// // Number of bytes switch(self->bitsNumber) { case 8: SciaRegs.SCICCR.bit.SCICHAR = 0x7; break; case 7: SciaRegs.SCICCR.bit.SCICHAR = 0x6; break; default: SciaRegs.SCICCR.bit.SCICHAR = 0x7; } // Parity settings switch(self->parityType){ case SERIAL_PARITY_EVEN: SciaRegs.SCICCR.bit.PARITYENA = 1; SciaRegs.SCICCR.bit.PARITY = 1; break; case SERIAL_PARITY_ODD: SciaRegs.SCICCR.bit.PARITYENA = 1; SciaRegs.SCICCR.bit.PARITY = 0; break; case SERIAL_PARITY_NONE: SciaRegs.SCICCR.bit.PARITYENA = 0; break; default: SciaRegs.SCICCR.bit.PARITYENA = 0; } // Baud rate settings - Automatic depending on self->baudrate baudrate = (Uint32) (LSPCLK / (self->baudrate*8) - 1); // Configure the High and Low baud rate registers SciaRegs.SCIHBAUD = (baudrate & 0xFF00) >> 8; SciaRegs.SCILBAUD = (baudrate & 0x00FF); // Enables TX and RX Interrupts SciaRegs.SCICTL2.bit.TXINTENA = 0; SciaRegs.SCIFFTX.bit.TXFFIENA = 0; SciaRegs.SCICTL2.bit.RXBKINTENA = 0; SciaRegs.SCIFFRX.bit.RXFFIENA = 0; // FIFO TX configurations SciaRegs.SCIFFTX.bit.TXFFIL = 1; // Interrupt level SciaRegs.SCIFFTX.bit.SCIFFENA = 1; // Enables FIFO SciaRegs.SCIFFTX.bit.TXFFINTCLR = 1; // Clear interrupt flag // FIFO: RX configurations SciaRegs.SCIFFRX.bit.RXFFIL = 1; // Interrupt level SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1; // Clear interrupt flag SciaRegs.SCIFFRX.bit.RXFFOVRCLR = 1; // Clear overflow flag // FIFO: Control configurations SciaRegs.SCIFFCT.all=0x00; // Enable RX and TX and reset the serial SciaRegs.SCICTL1.bit.RXENA = 1; SciaRegs.SCICTL1.bit.TXENA = 1; SciaRegs.SCICTL1.bit.SWRESET = 1; // FIFO: Reset SciaRegs.SCIFFRX.bit.RXFIFORESET = 1; SciaRegs.SCIFFTX.bit.TXFIFOXRESET = 1; SciaRegs.SCIFFTX.bit.SCIRST = 0; SciaRegs.SCIFFTX.bit.SCIRST = 1; SERIAL_DEBUG(); }
// Enable or disable TX (trasmiter) void serial_setSerialTxEnabled(bool status){ SERIAL_DEBUG(); SciaRegs.SCICTL1.bit.TXENA = status; }
bool serial_getRxError(){ SERIAL_DEBUG(); return SciaRegs.SCIRXST.bit.RXERROR; }
UINT32 cmd_stbid(unsigned int argc, unsigned char *argv[]) { UINT8 i = 0, j = 0, ch = 0xff; UINT8 *_stbid_flag = "SRI"; INT32 _stbid_flag_len = 3; UINT8 _serial_data[1024]; // max receive 1KB data UINT32 timeout = 1000, stbid_offset = STB_HWINFO_SERIAL_OFF, _stbid_crc = 0, _stbid_len = 0, _serial_len = 0, _crc = 0, _crc_pos = 0; UINT8 *buffer = NULL; UINT32 nReturn = SUCCESS; UINT32 nPacketNum = 0; PACKET packet; UINT32 tick = osal_get_tick(); UINT8 retry_num = 5, _tr_num = 5; ID _task_id = g_com_ash_id; osal_task_dispatch_off(); SendStatusPacket(COMMAND_STATUS_OK, 0); pan_display(g_pan_dev, "Stb-", 4); RETRY: _tr_num = 5; //transfer data MEMSET(&packet, 0, sizeof(PACKET)); nReturn = packet_receive(&packet, 5 * 1000); if(SUCCESS != nReturn) { SERIAL_DEBUG("receive packet fail!\n"); retry_num--; goto RETURN; } if(packet.packet_type == PACKET_DATA) { _serial_len = packet.packet_length-4; MEMCPY(_serial_data, packet.data_buffer+4, packet.packet_length-4); } else { SERIAL_DEBUG("receive %d packet, ignore!\n", packet.packet_type); retry_num--; goto RETURN; } SERIAL_DEBUG("stbid get data total len %d finish, data: \n", _serial_len); for(i=0; i<_serial_len; i++) { SERIAL_DEBUG("%c", _serial_data[i]); } SERIAL_DEBUG("\n"); pan_display(g_pan_dev, "GET", 4); if((_serial_data[0] != _stbid_flag[0]) || (_serial_data[1] != _stbid_flag[1]) || (_serial_data[2] != _stbid_flag[2])) // received flag tag { SERIAL_DEBUG("Error: SRI flag missing!\n"); retry_num--; goto RETURN; } pan_display(g_pan_dev, "FLAG", 4); _stbid_len = _serial_len-4-8; if(_stbid_len > STB_HWINFO_MAC_OFF) { SERIAL_DEBUG("Error: stbid len %d != [%d], please resend cmd!\n", _stbid_len, STB_HWINFO_MAC_OFF); retry_num--; goto RETURN; } pan_display(g_pan_dev, "LENG", 4); // do crc check _crc_pos = _stbid_flag_len+1+_stbid_len; _stbid_crc = 0; for(i=0; i<8; i++) { _stbid_crc |= (((_serial_data[_crc_pos+i]>'9') ? (_serial_data[_crc_pos+i]-'A'+10) : (_serial_data[_crc_pos+i]-'0'))<<((7-i)*4)); } _crc = MG_Table_Driven_CRC(0xFFFFFFFF, _serial_data, _crc_pos); if(_stbid_crc != _crc) { // fail, need re-trans SERIAL_DEBUG("stbid crc fail, calcu = 0x%x!\n", _crc); retry_num--; goto RETURN; } pan_display(g_pan_dev, "CRC", 4); // burn code, enable drive auto-erase for(i=0; i<(STB_HWINFO_OUI_OFF-STB_HWINFO_MAC_OFF); i++) // init mac { ch = _serial_data[STB_HWINFO_MAC_OFF+4-12+i*2]; _serial_data[i+STB_HWINFO_MAC_OFF+4] = (((ch>'9') ? ((ch>='a') ? (ch-'a'+10) : (ch-'A'+10)) : (ch-'0'))<<4); ch = _serial_data[STB_HWINFO_MAC_OFF+4-12+i*2+1]; _serial_data[i+STB_HWINFO_MAC_OFF+4] |= ((ch>'9') ? ((ch>='a') ? (ch-'a'+10) : (ch-'A'+10)) : (ch-'0')); } buffer = MALLOC(64*1024); if(buffer == NULL) { SDBBP(); } sto_io_control(g_sto_dev, STO_DRIVER_SECTOR_BUFFER, (UINT32)buffer); sto_io_control(g_sto_dev, STO_DRIVER_SET_FLAG, STO_FLAG_AUTO_ERASE|STO_FLAG_SAVE_REST); SERIAL_DEBUG("Now burn stbid: "); for(i=0; i<STB_HWINFO_OUI_OFF; i++) { SERIAL_DEBUG("%c", _serial_data[i+_stbid_flag_len+1]); } SERIAL_DEBUG("\n"); sto_put_data(g_sto_dev, STB_HWINFO_BASE_ADDR, &_serial_data[_stbid_flag_len+1], STB_HWINFO_OUI_OFF); if(buffer) { FREE(buffer); buffer = NULL; sto_io_control(g_sto_dev, STO_DRIVER_SECTOR_BUFFER, 0); sto_io_control(g_sto_dev, STO_DRIVER_SET_FLAG, 0); } if(g_stb_hwinfo != NULL) { FREE(g_stb_hwinfo); g_stb_hwinfo = NULL; } pan_display(g_pan_dev, "-tr-", 4); SERIAL_DEBUG("stbid finish, task %d deleted!\n", g_com_ash_id); SERIAL_DEBUG("cmd_stbid takes %dms\n", osal_get_tick()-tick); retry_num = 0; RESEND: SendStatusPacket(COMMAND_STATUS_DONE, 0); MEMSET(&packet, 0, sizeof(PACKET)); osal_task_sleep(100); nReturn = packet_receive(&packet, 5 * 1000); if((SUCCESS != nReturn) || (packet.packet_type != PACKET_STATUS)) { if(_tr_num-- > 0) { SERIAL_DEBUG("stbid finish, but signal send fail, now re-send!\n"); goto RESEND; } else { pan_display(g_pan_dev, "dStb", 4); // done, but notice fail! } } else { pan_display(g_pan_dev, "-Stb", 4); // done, all ok! } RETURN: if(retry_num >0) { SendStatusPacket(COMMAND_STATUS_ERROR, 0); goto RETRY; } else { SERIAL_DEBUG("error, please redo!\n"); api_set_com_check_flag(COM_MONITOR_CHECK_STBID); } g_com_ash_id = INVALID_ID; osal_task_dispatch_on(); osal_task_delete(_task_id); }