A9139M0 FIFO extension to 16KByte 資料 (DataRate:2Mbps)
本篇介紹A9139M0 使用FIFO extension to Max Data 16Kbyte
P.S. Amiccom的A9139M0其實就是A9129M0的 High TX Power版,所以在寄存器的使用上可以交互參考A9129M0的規格書使用(因為A9139M0規格書上會出現有些寄存器沒有詳細被記載到,但可以在A9129M0的規格書上找到)
這裡需要更正一下A9139M0規格書上的普通FIFO應改成 每包Data Max應該為256 Byte,"FEP=0xFF"
P.S.值得注意的是,雖然A9139M0 可以支持到16K byte的 RF資料,但是由於這顆M0核的Soc只有16KB的SRAM (扣除一些需要存放的變數/量),會出現無法一次性存放16K Byte的RF 資料
因此建議可以將SRAM Buffer裡的資料定義成256byte,依次小包小包處理並釋放空間出來
詳細FIFO extension 的概念跟方法,之前有介紹過,可以參考此篇:FIFO Extension介紹
代碼:
RC_A9139M0_x1_433MHz Band Ref. Code for FIFO 16384 byte-2M.zip
代碼解說:
(一).Tx部分
1.定義:FIFO長度=16384 Byte並設定FEP[13:0]=0x3FF,修改FPM[1:0]=11也就是margin =16 Byte,這裡使用代數'p'當作是餘量的計算
FIFO_Length = 16384; //Set FIFO Length RADIO->FIFOCTRL = FIFO_Length -1; RADIO->FIFOCTRL |= 0x00C00000, p = 16; //FPM=11 addr = 0;//用來計算傳送到第幾Byte
2.設定RFINT為WTR 中斷 & 設定GPIO1=FMTFO;GPIO2=EOAC; CKO=DCK Mode
3.計算'k'值,因P=16,也就是當RF發送到第240Byte 時(FPF 會Go High),通知MCU繼續對TX FIFO REG填入下一包 240Byte的data,所以需要將FIFO_Length/240得出整數部分=需要發送68包(由於第1包已經預先存在TX FIFO REG裡,因此後面計算會將K-1做處理)
4.計算'm'值,也就是剩餘的最後一包的Data數量
RADIO->RFINT_WRITE = 0x00000041; //WTR RADIO->RFGIO = 0x0700010F; //FMTDO,EOAC and DCK k = (FIFO_Length) / (256 - p); m = (FIFO_Length) % (256 - p);
P.S. 第1包會先打滿256Byte,後續才會根據每包240Byte依次傳送
5.首先進standby mode然後Reset tx point
6.這裡num的話,指的是待會要傳送出去的資料內容
7.使用一個for 256的迴圈,將num值每次+1並依序填入Tx FIFO Reg
8.並觀察addr是否>256,因為Tx FIFO Reg最多只有256個空間,每當填到第0x500014FF時,就要重新循環到0x50001400的位置填值
9.發送Tx CMD,等待GIO2=1(也就是EOAC=1,表示TX成功傳送完ID CODE)
10.將GIO2改設定成FPF Mode
RFLIB_StrobeCmd(CMD_STBY); RADIO->RESET = TXPOINT_RST; num = 0; addr=0; for(i=0; i<256; i++) { HW8_REG(0x50001400+(addr)) = num; addr++; num++; if(addr==256) { addr=0; } } RFLIB_StrobeCmd(CMD_TX); while(GIO2 == 0); GPIO0->DATAOUT_PIN.P00 =1; RADIO->RFGIO = 0x07000D0F; //FMTDO,FPF and DCK
11.使用for(k-1)將剩下的67包傳送出去,這裡因為第1包已經預先存好在TX FIFO REG傳送出去,所以先前計算的k=68包,就需要-1,變成67包
12.先前GIO2已經改成是FPF Mode,因此可以觀察FPF=1時,表示可以開始填入第2包資料內容到TX FIFO REG裡面
13.再使用一個for(256-16),目的是為了計算後續的每小包的資料內容只能填入240Byte,需要留出16Byte的餘量
14.使用'i'當作要傳送的資料內容,依序+1傳送
15.這裡需要去觀察addr是否>256,當>256時就需要重新循環到0x50001400的位置填值
for(j=0;j<k-1;j++) { while(GIO2==0); for(i=0; i<(256 - p); i++) { HW8_REG(0x50001400+(addr)) = i; addr++; if(addr==256) { addr=0; } num++; } }
16.觀察FPF=1時,表示可以將剩餘的'm'也就是剩餘的DATA填入TX FIFO REG裡傳送出去
17.使用i當作要傳送的Data,依序+1傳送
18.觀察addr是否>256,當>256時就需要重新循環到0x50001400的位置填值
if(m != 0) { while(GIO2==0); for(i=0; i<m; i++) { HW8_REG(0x50001400+(addr)) = i; addr++; if(addr==256) { addr=0; } num++; } }
19.等待RFINT(WTR) Flag=1,表示16K Byte資料全部發送結束
RF_Flag=0; while(RF_Flag==0); //wait receive completed GPIO0->DATAOUT_PIN.P00 =0; Delay10ms(1);
(二).Rx部分
1. 計算'k',因P=FPM=16也就是當FIFO Buffer=256-16=240 Byte為一小包,當接收到第240Byte 時mcu會繼續對RX Buffer讀出下一包的240Byte的data,所以需要將FIFO_Length/240得出整數部分=需要接收68包
2. 計算'm',也就是剩餘的最後一包的Data量
3.設定GPIO1=RXD;GPIO2=FPF; CKO=RCK Mode
k = (FIFO_Length) / (256 - p); m = (FIFO_Length) % (256 - p); RADIO->RFGIO = 0x07010D08; //RXD,FPF and RCK
4.設定GPIO1=RXD;GPIO2=Fsync; CKO=RCK Mode
5.Reset Rx point
6.進入RX mode
7.等待GIO2=1(表示ID Code成功掃描到)
8.設定GPIO1=RXD;GPIO2=FPF; CKO=RCK Mode
RADIO->RFGIO = 0x07010108; //RXD,Fsync and RCK addr=0; n=0; RADIO->RESET = RXPOINT_RST; RFLIB_StrobeCmd(CMD_RX); while(GIO2==0); RADIO->RFGIO = 0x07010D08; //RXD,FPF and RCK
9.使用for迴圈k=68次,也就是循環收68包
10.每當FPF=1時,執行for 240次,也就是循環收下當下封包的240Byte Data
11.將收到的資料依序從Rx FIFO Reg讀出,因為沒有足夠的空間可以存16K Byte資料,因此這邊採用循環檢查每包中的1個Byte作為檢查
12.觀察addr是否>256,因為Rx FIFO Reg最多只有256個空間,每當收到第0x500015FF時,就要重新循環到0x50001500的位置收值
方法如下:
採用'n'當作是包數的計算,'i'資料字節數的計算
13.設定GIO2=WTR Mode
14.判斷WTR拉LOW,表示RX結束
RADIO->RFGIO = 0x07010008; //RXD,WTR and RCK while(GIO2==1);
15.收完68包後,接著讀取剩餘的'm'資料量
16.這裡取剩餘的最後1byte存入TmpBuf裡