 Apтём (24.08.2013 21:34 - 21:45, просмотров: 230) ответил Adept на чё-то не вкурил по поводу аппаратного CRC в XMEGA с флешем всё понятно, но вот с ОЗУ как? Через DMA считать, или вообще никак ?? :((
 Apтём (24.08.2013 21:34 - 21:45, просмотров: 230) ответил Adept на чё-то не вкурил по поводу аппаратного CRC в XMEGA с флешем всё понятно, но вот с ОЗУ как? Через DMA считать, или вообще никак ?? :((
С озу накаких проблем нет - можно через DMA, можно записью в регистр. С флешем криво. 
volatile uint8_t DmaComplete;
ISR (DMA_CH0_vect)
{
	DMA.CH0.CTRLB =
		0
		| (0<<DMA_CH_CHBUSY_bp)
		| (0<<DMA_CH_CHPEND_bp)
		| (1<<DMA_CH_ERRIF_bp)
		| (1<<DMA_CH_TRNIF_bp)
		| DMA_CH_ERRINTLVL_OFF_gc
		| DMA_CH_TRNINTLVL_OFF_gc
		;
	DmaComplete=1;
}
void UpdateCRCWithDma(uint8_t * data, uint16_t length, bool crc32_mode)
{
	CRC.CTRL=
		0
		| CRC_RESET_RESET1_gc
		| CRC_SOURCE_IO_gc
		| (crc32_mode ? (1<<CRC_CRC32_bp) : (0<<CRC_CRC32_bp))
		;
	CRC.CTRL=
		0
		| CRC_RESET_NO_gc
		| CRC_SOURCE_DMAC0_gc
		| (crc32_mode ? (1<<CRC_CRC32_bp) : (0<<CRC_CRC32_bp))
		;
	DMA.CH0.ADDRCTRL=
		0
		| DMA_CH_SRCRELOAD_NONE_gc
		| DMA_CH_SRCDIR_INC_gc
		| DMA_CH_DESTRELOAD_NONE_gc
		| DMA_CH_DESTDIR_INC_gc
		;
	DMA.CH0.TRIGSRC=DMA_CH_TRIGSRC_OFF_gc;
	DMA.CH0.REPCNT=0;
	uint16_t dma_address=(uint16_t)data;
	DMA.CH0.DESTADDR0= dma_address & 0xFF;
	DMA.CH0.DESTADDR1=dma_address>>8;
	DMA.CH0.DESTADDR2=0;
	DMA.CH0.SRCADDR0= dma_address & 0xFF;
	DMA.CH0.SRCADDR1=dma_address>>8;
	DMA.CH0.SRCADDR2=0;
	DMA.CH0.TRFCNT=length;
	
	DMA.CH0.CTRLB =
		0
		| (0<<DMA_CH_CHBUSY_bp)
		| (0<<DMA_CH_CHPEND_bp)
		| (1<<DMA_CH_ERRIF_bp)
		| (1<<DMA_CH_TRNIF_bp)
		| DMA_CH_ERRINTLVL_HI_gc
		| DMA_CH_TRNINTLVL_HI_gc
	uint8_t burst_size=DMA_CH_BURSTLEN_1BYTE_gc;
	if ((length&1)==0)
		burst_size=DMA_CH_BURSTLEN_2BYTE_gc;
	if ((length&3)==0)
		burst_size=DMA_CH_BURSTLEN_4BYTE_gc;
	if ((length&7)==0)
		burst_size=DMA_CH_BURSTLEN_8BYTE_gc;
	SLEEP.CTRL=
		0
		| SLEEP_SMODE_IDLE_gc
		| 1<<SLEEP_SEN_bp
		;
	DMA.CH0.CTRLA=
		0
		| (1<<DMA_CH_ENABLE_bp)
		| (0<<DMA_CH_RESET_bp)
		| (0<<DMA_CH_REPEAT_bp)
		| (1<<DMA_CH_TRFREQ_bp)
		| (0<<DMA_CH_SINGLE_bp)
		| burst_size
		;
	
	
	asm ("sleep");
	
	while (DmaComplete==0) {
		asm("sleep");
	}
	DmaComplete=0;
	SLEEP.CTRL=
		0
		| SLEEP_SMODE_IDLE_gc
		| 0<<SLEEP_SEN_bp
		;
	if (crc32_mode==false)
		CRC16=CRC.CHECKSUM0+(CRC.CHECKSUM1<<8);
	else {
		uint8_t *result=(uint8_t *)&CRC32;
		*result++=CRC.CHECKSUM0;
		*result++=CRC.CHECKSUM1;
		*result++=CRC.CHECKSUM2;
		*result++=CRC.CHECKSUM3;
	}
}
volatile uint16_t CRC16;
volatile uint32_t CRC32;
extern "C" void Calculate_Crc_32_Byte(uint8_t *data_ptr);
void UpdateCrc(uint8_t * data, uint16_t length)
{
	CRC.CTRL=
		0
		| CRC_RESET_RESET1_gc
		| CRC_SOURCE_IO_gc
		| (0<<CRC_CRC32_bp)
		;
	CRC.CTRL=
		0
		| CRC_RESET_NO_gc
		| CRC_SOURCE_IO_gc
		| (0<<CRC_CRC32_bp)
		;
	while (length) {
		if (length>=32) {
			length-=32;
			Calculate_Crc_32_Byte(data); // функция на ассемблере
			data+=32;
		}
		else {
			CRC.DATAIN=*data++;
			length--;
		}
	}
	CRC16=CRC.CHECKSUM0+(CRC.CHECKSUM1<<8);
}
extern uint8_t Packet2[520];
void main()
{
DMA.CTRL=DMA_ENABLE_bm;
	PMIC.CTRL=
		0
		| (0<<PMIC_RREN_bp)
		| (0<<PMIC_IVSEL_bp)
		| (1<<PMIC_HILVLEN_bp)
		| (1<<PMIC_MEDLVLEN_bp)
		| (1<<PMIC_LOLVLEN_bp)
		;
	
	sei();
	UpdateCrc((uint8_t * )Packet2, sizeof(Packet2));
	asm("nop");
	asm("nop");
	UpdateCRCWithDma(Packet2, sizeof(Packet2), false);
	while (1);
}