Apтём (24.08.2013 21:34 - 21:45, просмотров: 180) ответил 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);
}