void txstring(unsigned char app, unsigned char verb, const char *str) { unsigned long len = strlen(str); txhead(app, verb, len); while (len--) uart_putc(*(str++)); }
void txdata(unsigned char app, unsigned char verb, unsigned long len) { unsigned int i = 0; // if(silent) return; txhead(app, verb, len); for (i = 0; i < len; i++) { serial_tx(cmddata[i]); } }
/*! \brief Transmit debug bytes. Transmits bytes for debugging. */ void debugbytes(const char *bytes, unsigned int len) { u16 i; txhead(0xFF,0xFE,len); for(i=0; i<len; i++) serial_tx(bytes[i]); }
//! Handles MSP430X2 JTAG commands. Forwards others to JTAG. void jtag430x2_handle_fn( uint8_t const app, uint8_t const verb, uint32_t const len) { unsigned int i,val; unsigned long at, l; //jtag430_resettap(); if(verb!=START && jtag430mode==MSP430MODE){ (*(jtag430_app.handle))(app,verb,len); return; } switch(verb){ case START: //Enter JTAG mode. //do cmddata[0]=jtag430x2_start(); //while(cmddata[0]==00 || cmddata[0]==0xFF); //MSP430 or MSP430X if(jtagid==MSP430JTAGID){ //debugstr("ERROR, using JTAG430X2 instead of JTAG430!"); jtag430mode=MSP430MODE; /* So the way this works is that a width of 20 does some backward-compatibility finagling, causing the correct value to be exchanged for addresses on 16-bit chips as well as the new MSP430X chips. (This has only been verified on the MSP430F2xx family. TODO verify for others.) */ drwidth=20; //Perform a reset and disable watchdog. jtag430_por(); jtag430_writemem(0x120,0x5a80);//disable watchdog jtag430_haltcpu(); jtag430_resettap(); txdata(app,verb,1); return; }else if(jtagid==MSP430X2JTAGID){ jtag430mode=MSP430X2MODE; drwidth=20; }else{ debugstr("JTAG version unknown."); txdata(app,NOK,1); return; } jtag430x2_fusecheck(); jtag430x2_syncpor(); jtag430_resettap(); txdata(app,verb,1); break; case JTAG430_READMEM: case PEEK: at=cmddatalong[0]; //Fetch large blocks for bulk fetches, //small blocks for individual peeks. if(len>5) l=(cmddataword[2]);//always even. else l=2; l&=~1;//clear lsbit if(l<2) l=2; txhead(app,verb,l); for(i=0;i<l;i+=2){ //jtag430_resettap(); //delay(10); val=jtag430x2_readmem(at); at+=2; serial_tx(val&0xFF); serial_tx((val&0xFF00)>>8); } break; case JTAG430_COREIP_ID: cmddataword[0]=jtag430_coreid(); txdata(app,verb,2); break; case JTAG430_DEVICE_ID: cmddatalong[0]=jtag430_deviceid(); txdata(app,verb,4); break; case JTAG430_WRITEFLASH: case JTAG430_WRITEMEM: case POKE: jtag430x2_writemem(cmddatalong[0], cmddataword[2]); cmddataword[0]=jtag430x2_readmem(cmddatalong[0]); txdata(app,verb,2); break; //unimplemented functions case JTAG430_HALTCPU: //jtag430x2_haltcpu(); debugstr("Warning, not trying to halt for lack of code."); txdata(app,verb,0); break; case JTAG430_RELEASECPU: case JTAG430_SETINSTRFETCH: case JTAG430_ERASEFLASH: case JTAG430_SETPC: debugstr("This function is not yet implemented for MSP430X2."); debughex(verb); txdata(app,NOK,0); break; default: (*(jtag_app.handle))(app,verb,len); } jtag430_resettap(); }
int main(void) { // Set up Timer2 (normal mode), freq ~55 Hz TCCR2B = (1 << CS22) | (1 << CS21) | (1 << CS20); // Fcpu/1024 TIMSK2 = (1 << TOIE2); // Enable timer overflow interrupt DDRB |= (1 << PB5); // LED led_off(); uart_init(UART_BAUD_SELECT_DOUBLE_SPEED(BAUD, F_CPU)); /* * now enable interrupts... */ sei(); msdelay(10); byte min = 0; byte packet[4]; byte i = 0; while (1) { unsigned int data = uart_rx(); // flush packet if data is invalid if (data & 0xff00) { if (i >= min) { txhead(JTAG430X2, NOK, 0); min = 1; } i = 0; continue; } packet[i++] = data; if (i < 4) { continue; // keep looking for further bytes } byte app = packet[0]; byte verb = packet[1]; int len = packet[2] + 256 * packet[3]; byte ok = 1; // read the data for (i = 0; i < len; i++) { data = uart_rx(); if (data & 0xff00) { ok = 0; break; } if (i < CMDDATALEN) { cmddata[i] = data & 0xff; } else { ok = 0; // just ignore the extra bytes } } if (ok && app == JTAG430X2) { // start processing jtag430x2_app.handle(app, verb, len); } else { txhead(JTAG430X2, NOK, 0); } i = 0; } }