INTEL (Altera) USB Byte Blaster pada STM32

Seringkali, jika perangkat memiliki logika yang dapat diprogram, prosesor / mikrokontroler juga ada.





Pada titik tertentu, saya bosan memasang kabel konektor JTAG di papan, itu memakan banyak ruang di papan dan, sebenarnya, hanya diperlukan untuk pengembangan. Di perangkat terakhir, itu sama sekali tidak perlu.





Sangat sering saya menggunakan SignalTap II Logic Analyzer untuk memeriksa kebenaran penerapan kode Verilog atau bahkan "melihat bagaimana pemberi sinyal berjalan", masalahnya nyaman dan intuitif, saya rasa banyak yang akan langsung mengenalinya dari gambar:





JTAG?





CPLD .





.





STM32F103RCT6 USB Byte Blaster. CPLD EPM3064.





, :





PC12->TDI





PC13->TMS





PC14->TCK





PC15->TDO





USB , :





USB Descriptor
/* USB Standard Device Descriptor */
const BYTE USB_DeviceDescriptor[] = {
  USB_DEVICE_DESC_SIZE,              /* bLength */
  USB_DEVICE_DESCRIPTOR_TYPE,        /* bDescriptorType */
  WBVAL(0x0110), /* 1.10 */          /* bcdUSB */
    0x00,                   // Class Code
    0x00,                   // Subclass code
    0x00,                   // Protocol code
    USB_MAX_PACKET0,          // Max packet size for EP0, see usbcfg.h
  WBVAL(0x09FB),                     /* idVendor */
  WBVAL(0x6001),                     /* idProduct */
  WBVAL(0x0400), /* 1.00 */          /* bcdDevice */
    0x01,                   // Manufacturer string index
    0x02,                   // Product string index
    0x03,                   // Device serial number string index
    0x01                    // Number of possible configurations	
};

/* USB Configuration Descriptor */
/*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
const BYTE USB_ConfigDescriptor[] = {
    /* Configuration Descriptor */
  USB_CONFIGUARTION_DESC_SIZE,       /* bLength */
  USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */
/* Configuration 1 */
  WBVAL(                            /* wTotalLength */
    (1*USB_CONFIGUARTION_DESC_SIZE) +
    (1*USB_INTERFACE_DESC_SIZE) +
    (2*USB_ENDPOINT_DESC_SIZE)
  ),
    1,                      // Number of interfaces in this cfg
    1,                      // Index value of this configuration
    0,                      // Configuration string index
  USB_CONFIG_SELF_POWERED, /*|*/       /* bmAttributes */
  USB_CONFIG_POWER_MA(80),          /* bMaxPower */

    /* Interface Descriptor */
  USB_INTERFACE_DESC_SIZE,           /* bLength */
  USB_INTERFACE_DESCRIPTOR_TYPE,     /* bDescriptorType */
/* Interface 0, Alternate Setting 0, MSC Class */
  0x00,                              /* bInterfaceNumber */
  0x00,                              /* bAlternateSetting */
  0x02,                              /* bNumEndpoints */
    0xFF,                   // Class code
    0xFF,                   // Subclass code
    0xFF,                   // Protocol code
    0,                      // Interface string index
    
    /* Endpoint Descriptor */
/* Bulk In Endpoint */
  USB_ENDPOINT_DESC_SIZE,            /* bLength */
  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType */
  USB_ENDPOINT_IN(BLST_EP_IN & 0x0F),                /* bEndpointAddress */
  USB_ENDPOINT_TYPE_BULK,            /* bmAttributes */
  WBVAL(BLST_MAX_PACKET),                     /* wMaxPacketSize */
    10,                         //Interval
    
  USB_ENDPOINT_DESC_SIZE,            /* bLength */
  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType */
  USB_ENDPOINT_OUT(BLST_EP_OUT & 0x0F),               /* bEndpointAddress */
  USB_ENDPOINT_TYPE_BULK,            /* bmAttributes */
  WBVAL(BLST_MAX_PACKET),                     /* wMaxPacketSize */
    10                          //Interval	
/* Terminator */
  ,0                                  /* bLength */
};

//Language code string descriptor
ROM struct{BYTE bLength;BYTE bDscType;WORD string[1];}sd000={
sizeof(sd000),USB_STRING_DESCRIPTOR_TYPE,{0x0409}};

//Manufacturer string descriptor
ROM struct{BYTE bLength;BYTE bDscType;WORD string[6];}sd001={
sizeof(sd001),USB_STRING_DESCRIPTOR_TYPE,
{'A','l','t','e','r','a'}};

//Product string descriptor
ROM struct{BYTE bLength;BYTE bDscType;WORD string[11];}sd002={
sizeof(sd002),USB_STRING_DESCRIPTOR_TYPE,
{'U','S','B','-','B','l','a','s','t','e','r'}};

//Serial string descriptor
ROM struct{BYTE bLength;BYTE bDscType;WORD string[8];}sd003={
sizeof(sd003),USB_STRING_DESCRIPTOR_TYPE,
{'0','0','0','0','0','0','0','0'}};

//Array of configuration descriptors
ROM BYTE *ROM USB_CD_Ptr[]=
{
    (ROM BYTE *)&USB_ConfigDescriptor
};
//Array of string descriptors
ROM BYTE *ROM USB_SD_Ptr[]=
{
    (ROM BYTE *)&sd000,
    (ROM BYTE *)&sd001,
    (ROM BYTE *)&sd002,
    (ROM BYTE *)&sd003
};

/* USB String Descriptor (optional) */
const BYTE *USB_StringDescriptor = (const BYTE *)USB_SD_Ptr;
      
      







"" Byte Blaster'a:





blaster.c
BYTE fifo_wp,fifo_rp;
BYTE InFIFO[256];

BYTE nCS = 0;

DWORD PacketPos = 0;
BYTE InPacket[64];
BYTE OutPacket[128];
BYTE ep1_ready = 1;

void EP2CallBack(void)
{
	ProcBlasterData();
}

void ProcBlasterData(void)
{
	int bufptr = 0;
	static BYTE jtag_byte = 0, read = 0, aser_byte = 0;
	DWORD recv_byte;
	BYTE acc0, acc1;
	
	recv_byte = USB_ReadEP(BLST_EP_OUT, OutPacket);

	bufptr = 0;
	
	if(!recv_byte) return;
	LED_RD_ON();
	
	do
	{
		if (jtag_byte)
		{
			if (!read)
			{
				do
				{

					acc0 = OutPacket[bufptr++];
					JTAG_Write(acc0);
					jtag_byte--;
					recv_byte--;
				} while (jtag_byte && recv_byte);
			}
			else
			{
				do
				{

					acc0 = OutPacket[bufptr++];
					acc1 = JTAG_RW(acc0);
					enqueue(acc1);
					jtag_byte--;
					recv_byte--;
				} while (jtag_byte&&recv_byte);
			}

		}
		else if (aser_byte)
		{
			if (!read)
			{

				do
				{

					acc0 = OutPacket[bufptr++];
					JTAG_Write(acc0);
					aser_byte--;
					recv_byte--;
				} while (aser_byte&&recv_byte);
			}
			else
			{
				do {
					acc0 = OutPacket[bufptr++];
					acc1 = ASer_RW(acc0);
					enqueue(acc1);
					aser_byte--;
					recv_byte--;
				} while (aser_byte&&recv_byte);
			}
		}
		else
		{
			do
			{
				acc0 = OutPacket[bufptr++];
				_bitcopy(bitmask(acc0, 6), read);
				if (bitmask(acc0, 7))
				{		//EnterSerialMode
					LTCK(0);		//bug fix
					
					if (nCS & 0x8) 
					{	//nCS=1:JTAG
						jtag_byte = acc0 & 0x3F;
					}
					else 
					{		//nCS=0:ActiveSerial
						aser_byte = acc0 & 0x3F;
					}
					/* Always JTAG Made */
					recv_byte--;
					break;
				}
				else
				{			//BitBangMode
					OUTP(acc0);
					if (read) {
						acc1 = 0;
						if (PADO) acc1 |= 0x02;
						if (PTDO) acc1 |= 0x01;
						enqueue(acc1);
					}
					recv_byte--;
				}
			} while (recv_byte);
		}
	} while (recv_byte);

	/* Disable RD LED */
	LED_RD_OFF();
	return;
}

void EP1CallBack(void)
{
	ep1_ready = 1;

	return;
}

void OUTP(BYTE b)
{
	unsigned int uiPortState = GPIOC->ODR;
	/* 	TCK - 0
			TMS - 1
			nCE - 2
			nCS - 3
	x - 5,6
			TDI - 4,7
	*/
	if(b & (1 << 3)) /* nCS */
		nCS = 0x08;
	else
		nCS = 0;
	
	if(b & (1 << 0)) /* TCK */
		uiPortState |= (1 << 14);
	else
		uiPortState &= ~(1 << 14);

	if(b & (1 << 1)) /* TMS */
		uiPortState |= (1 << 13);
	else
		uiPortState &= ~(1 << 13);

	if(b & (1 << 4)) /* TDI */
		uiPortState |= (1 << 12);
	else
		uiPortState &= ~(1 << 12);
	
	GPIOC->ODR = uiPortState;
	
//	Nop();
	
	return;
}

void JTAG_Write(BYTE a) 
{
	int i;
	
	for(i = 0;i < 8;i ++)
	{
		bitcopy(a & (0x01 << i),LTDI);
		tck();
	}
}

BYTE JTAG_RW(BYTE a)
{
	BYTE bRet=0;
	int i = 0;
	
	for(i = 0;i < 8;i++)
	{
		bitcopy(a & (0x01 << i),LTDI);
		if(PTDO) bRet |= (0x01 << i);
		tck();
	}
	
	return bRet;
}

BYTE ASer_RW(BYTE a) {
	BYTE bRet=0;
	int i = 0;
	
	for(i = 0;i < 8;i++)
	{
		bitcopy(a & (0x01 << 1),LTDI);
		if(PADO) bRet|= (0x01 << 1);
		tck();
	}		
	
	return bRet;
}

extern USB_EP_DATA EP0Data;
BYTE bBuffer[10];

void USB_EP0BlasterReq(USB_SETUP_PACKET *SetupPacket)
{
	BYTE bIndex;

	if (SetupPacket->bmRequestType.BM.Dir == 0)
	{	//0utput
		//Responce by sending zero-length packet
		//I don't know if this way is right, but working:)
		USB_WriteEP(0x80, NULL, 0);
		return;
	}

	if (SetupPacket->bRequest == 0x90)
	{
		bIndex = (SetupPacket->wIndex.WB.L << 1) & 0x7E;
		bBuffer[0] = eeprom_read(bIndex);
		bBuffer[1] = eeprom_read(bIndex + 1);
	}
	else
	{
		bBuffer[0] = 0x36;
		bBuffer[1] = 0x83;
	}

	EP0Data.pData = bBuffer;
	EP0Data.Count = 2;
	//		USB_WriteEP(0x80, bBuffer, 2);

	return;
}

      
      







. , main() .





:





main.c
  while (1) 
	{
		if(USB_Configuration)
		{
			if(ep1_ready)
			{
				acc0 = fifo_used();
				if (62 <= acc0) 
				{		//send full packet to host
					LED_WR_ON();
					ep1_ready = 0;
					dequeue(&InPacket[2], 62);
					USB_WriteEP(BLST_EP_IN, InPacket, 64);
					ChargeTimer_ms(10);
				}
				else if(acc0 || IsTimerArrived())
				{
					if(acc0)
						LED_WR_ON();
					else						
						LED_WR_OFF();
					ep1_ready = 0;
					if(acc0)
						dequeue(&InPacket[2], acc0);
					USB_WriteEP(BLST_EP_IN, InPacket, acc0 + 2);
					ChargeTimer_ms(10);
				}
			}
		}
  } // end while
      
      







, :





Dan kami menghubungkan perangkat kami ke USB.





Dan itu pasti tidak berarti apa-apa. Karena penginstalan hanya dilakukan berdasarkan deskriptor perangkat, sekarang mari kita periksa apakah ini benar-benar Byte Blaster "asli".





Kami memilih:





Dan luncurkan JTAG Chain Debugger:





Bekerja !!! Kami dapat menulis CPLD langsung di perangkat kami.





Omong-omong, jika Anda menghubungkan implementasi ini ke FPGA, perekaman ke FPGA dan SignalTap II akan tersedia. Itu saja yang ingin saya katakan.









Terima kasih atas perhatiannya! Semoga berhasil dalam bisnis dan suasana hati yang baik!








All Articles