//
// Date init       14.12.2004
//
// Revision date   $Date:: 24-04-08 14:33                                    $
//
// Filename        $Workfile:: d_bt.r                                        $
//
// Version         $Revision:: 3                                             $
//
// Archive         $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_bt.r $
//
// Platform        C
//

#ifdef    SAM7S256

#if       defined (PROTOTYPE_PCB_3) || (PROTOTYPE_PCB_4)

#define   BT_RX_PIN                     AT91C_PIO_PA21
#define   BT_TX_PIN                     AT91C_PIO_PA22
#define   BT_SCK_PIN                    AT91C_PIO_PA23
#define   BT_RTS_PIN                    AT91C_PIO_PA24
#define   BT_CTS_PIN                    AT91C_PIO_PA25

#define   BT_CS_PIN                     AT91C_PIO_PA31
#define   BT_RST_PIN                    AT91C_PIO_PA11

#define   BT_ARM7_CMD_PIN               AT91C_PIO_PA27

#else

#endif

#define   BAUD_RATE                     460800L

#define   SIZE_OF_INBUF                 128
#define   NO_OF_INBUFFERS               2
#define   NO_OF_DMA_OUTBUFFERS          2
#define   SIZE_OF_OUTBUF                256

#define   PER_ID7_UART_1                0x80
#define   UART1_INQ                     0x80
#define   EXT_LEN_MSG_BIT               0x80

static    UBYTE  InBuf[NO_OF_INBUFFERS][SIZE_OF_INBUF];
static    ULONG  InBufPtrs[NO_OF_INBUFFERS];
static    UBYTE  InBufInPtr;
static    UBYTE  LengthSize;

static    UBYTE  OutDma[NO_OF_DMA_OUTBUFFERS][SIZE_OF_OUTBUF];
static    UBYTE  DmaBufPtr;
static    UBYTE  *pBuffer;

static    UBYTE  MsgIn;
static    UBYTE  InBufOutCnt;
static    UWORD  FullRxLength;
static    UWORD  RemainingLength;


#define   ENABLEDebugOutput             {\
                                          *AT91C_PIOA_PER = 0x20000000;                /* Enable PIO on PA029 */\
                                          *AT91C_PIOA_OER = 0x20000000;                /* PA029 set to Output  */\
                                        }

#define   SETDebugOutputHigh            *AT91C_PIOA_SODR  = 0x20000000

#define   SETDebugOutputLow             *AT91C_PIOA_CODR  = 0x20000000

#define   BTInit                        {\
                                          UBYTE Tmp;\
                                          LengthSize  = 1;\
                                          InBufInPtr = 0;\
                                          for(Tmp = 0; Tmp < NO_OF_INBUFFERS; Tmp++)\
                                          {\
                                            InBufPtrs[Tmp]   = (ULONG)&(InBuf[Tmp][0]);\
                                          }\
                                          *AT91C_PMC_PCER = PER_ID7_UART_1;                        /* Enable PMC clock for UART 1 */\
                                          *AT91C_PIOA_PDR = BT_RX_PIN | BT_TX_PIN | BT_SCK_PIN | BT_RTS_PIN | BT_CTS_PIN; /* Disable Per. A on PA21, PA22, PA23, PA24 & PA25 */\
                                          *AT91C_PIOA_ASR = BT_RX_PIN | BT_TX_PIN | BT_SCK_PIN | BT_RTS_PIN | BT_CTS_PIN; /* Enable Per. A on PA21, PA22, PA23, PA24 & PA25 */\
                                          *AT91C_US1_CR   = AT91C_US_RSTSTA;                       /* Resets pins on UART1 */\
                                          *AT91C_US1_CR   = AT91C_US_STTTO;                        /* Start timeout functionality after 1 byte */\
                                          *AT91C_US1_RTOR = 10000;                                 /* Approxitely 20 mS,x times bit time with 115200 bit pr s */\
                                          *AT91C_US1_IDR  = AT91C_US_TIMEOUT;                      /* Disable interrupt on timeout */\
                                          *AT91C_AIC_IDCR = UART1_INQ;                             /* Disable UART1 interrupt */\
                                          *AT91C_AIC_ICCR = UART1_INQ;                             /* Clear interrupt register */\
                                          *AT91C_US1_MR   = AT91C_US_USMODE_HWHSH;                 /* Set UART with HW handshake */\
                                          *AT91C_US1_MR  &= ~AT91C_US_SYNC;                        /* Set UART in asynchronous mode */\
                                          *AT91C_US1_MR  |= AT91C_US_CLKS_CLOCK;                   /* Clock setup MCK*/\
                                          *AT91C_US1_MR  |= AT91C_US_CHRL_8_BITS;                  /* UART using 8-bit */\
                                          *AT91C_US1_MR  |= AT91C_US_PAR_NONE;                     /* UART using none parity bit */\
                                          *AT91C_US1_MR  |= AT91C_US_NBSTOP_1_BIT;                 /* UART using 1 stop bit */\
                                          *AT91C_US1_MR  |= AT91C_US_OVER;                         /* UART is using 8-bit sampling */\
                                          *AT91C_US1_BRGR = ((OSC/8/BAUD_RATE) | (((OSC/8) - ((OSC/8/BAUD_RATE) * BAUD_RATE)) / ((BAUD_RATE + 4)/8)) << 16);\
                                          *AT91C_US1_PTCR = (AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS); /* Disable of TX & RX with DMA */\
                                          *AT91C_US1_RCR  = 0;                                     /* Receive Counter Register */\
                                          *AT91C_US1_TCR  = 0;                                     /* Transmit Counter Register */\
                                          *AT91C_US1_RNPR = 0;\
                                          *AT91C_US1_TNPR = 0;\
                                          Tmp             = *AT91C_US1_RHR;\
                                          Tmp             = *AT91C_US1_CSR;\
                                          *AT91C_US1_RPR  = (unsigned int)&(InBuf[InBufInPtr][0]);     /* Initialise receiver buffer using DMA */\
                                          *AT91C_US1_RCR  = SIZE_OF_INBUF;\
                                          *AT91C_US1_RNPR = (unsigned int)&(InBuf[(InBufInPtr + 1)%NO_OF_INBUFFERS][0]);\
                                          *AT91C_US1_RNCR = SIZE_OF_INBUF;\
                                          MsgIn           = 0;\
                                          InBufOutCnt     = 0;\
                                          FullRxLength    = 0;\
                                          RemainingLength = 0;\
                                          *AT91C_US1_CR   = AT91C_US_RXEN | AT91C_US_TXEN;         /* Enable Tx & Rx on UART 1*/\
                                          *AT91C_US1_PTCR = (AT91C_PDC_RXTEN | AT91C_PDC_TXTEN);   /* Enable of TX & RX with DMA */\
                                        }


#define   BTInitPIOPins                 {\
                                          *AT91C_PIOA_PER   = BT_CS_PIN | BT_RST_PIN;    /* Enable PIO on PA11 & PA31 */\
                                          *AT91C_PIOA_OER   = BT_CS_PIN | BT_RST_PIN;    /* PA11 & PA31 set to output */\
                                          *AT91C_PIOA_SODR  = BT_CS_PIN | BT_RST_PIN;    /* PA31 & PA11 set output high */\
                                          *AT91C_PIOA_PPUDR = BT_ARM7_CMD_PIN;           /* Disable PULL-UP resistor on PA27 */\
                                          *AT91C_PIOA_PER   = BT_ARM7_CMD_PIN;           /* Enable PIO on PA27 */\
                                          *AT91C_PIOA_CODR  = BT_ARM7_CMD_PIN;           /* PA27 set output low */\
                                          *AT91C_PIOA_OER   = BT_ARM7_CMD_PIN;           /* PA27 set to output */\
                                        }

#define   BTStartADConverter            {\
                                          *AT91C_ADC_CHER = AT91C_ADC_CH6 | AT91C_ADC_CH4;  \
                                          ADStart;                                          \
                                          while(!((*AT91C_ADC_SR) & AT91C_ADC_CH6));        \
                                          *AT91C_ADC_CHDR = AT91C_ADC_CH6 | AT91C_ADC_CH4;  \
                                        }

#define   BTReadADCValue(ADValue)       ADValue            = *AT91C_ADC_CDR6;

#define   BTSetResetHigh                {\
                                          *AT91C_PIOA_SODR = BT_RST_PIN;              /* PA11 set output high */\
                                        }

#define   BTSetResetLow                 {\
                                          *AT91C_PIOA_CODR = BT_RST_PIN;              /* PA11 set output low */\
                                        }

#define   BTInitReceiver(InputBuffer, Mode)\
                                       {\
                                          pBuffer         = InputBuffer;\
                                          MsgIn           = 0;\
                                          FullRxLength    = 0;\
                                          if (STREAM_MODE == Mode)\
                                          {\
                                            LengthSize = 2;\
                                          }\
                                          else\
                                          {\
                                            LengthSize = 1;\
                                          }\
                                        }

#define   BT_SetArm7CmdPin              *AT91C_PIOA_SODR = BT_ARM7_CMD_PIN

#define   BT_ClearArm7CmdPin            *AT91C_PIOA_CODR = BT_ARM7_CMD_PIN

#define   BT_GetBc4CmdPin               *AT91C_PIOA_PDSR & BT_BC4_CMD_PIN

#define   REQTxEnd(TxEnd)               TxEnd = FALSE;\
                                        if ((!(*AT91C_US1_TNCR)) && (!(*AT91C_US1_TCR)))\
                                        {\
                                          TxEnd = TRUE;\
                                        }

#define   AVAILOutBuf(Avail)            if (!(*AT91C_US1_TNCR))\
                                        {\
                                          Avail = SIZE_OF_OUTBUF;\
                                        }\
                                        else\
                                        {\
                                          Avail = 0;\
                                        }


#define   BTSend(OutputBuffer, BytesToSend)\
                                        {\
                                          UWORD Avail;\
                                          AVAILOutBuf(Avail);\
                                          if (BytesToSend < (Avail - 1))\
                                          {\
                                            memcpy(&(OutDma[DmaBufPtr][0]), OutputBuffer, BytesToSend);\
                                            *AT91C_US1_TNPR = (unsigned int)&(OutDma[DmaBufPtr][0]);\
                                            *AT91C_US1_TNCR = BytesToSend;\
                                            DmaBufPtr = (DmaBufPtr + 1) % NO_OF_DMA_OUTBUFFERS;\
                                          }\
                                        }


#define   BTSendMsg(OutputBuffer, BytesToSend, MsgSize)\
                                        {\
                                          UWORD Avail;\
                                          AVAILOutBuf(Avail);\
                                          if (BytesToSend < (Avail - 1))\
                                          {\
                                            if (2 == LengthSize)\
                                            {\
                                              OutDma[DmaBufPtr][0] = (UBYTE)MsgSize;\
                                              OutDma[DmaBufPtr][1] = (UBYTE)(MsgSize>>8);\
                                            }\
                                            else\
                                            {\
                                              OutDma[DmaBufPtr][0] = (UBYTE)MsgSize;\
                                            }\
                                            memcpy(&(OutDma[DmaBufPtr][LengthSize]), OutputBuffer, BytesToSend);\
                                            *AT91C_US1_TNPR = (unsigned int)&(OutDma[DmaBufPtr][0]);\
                                            *AT91C_US1_TNCR = BytesToSend + LengthSize;\
                                            DmaBufPtr = (DmaBufPtr + 1) % NO_OF_DMA_OUTBUFFERS;\
                                          }\
                                        }


#define   BTReceivedData(pByteCnt, pToGo)\
                                        {\
                                          UWORD InCnt, Cnt;\
                                          *pByteCnt = 0;\
                                          *pToGo    = 0;\
                                          InCnt = (SIZE_OF_INBUF - *AT91C_US1_RCR);\
                                          if (*AT91C_US1_RNCR == 0)\
                                          {\
                                            InCnt = SIZE_OF_INBUF;\
                                          }\
                                          InCnt -= InBufOutCnt; /* Remove already read bytes */\
                                          if (InCnt)\
                                          {\
                                            if (0 == FullRxLength)  /* FullRxLength still to be calculated */\
                                            {\
                                              while((MsgIn < LengthSize) && (InCnt > 0))\
                                              {\
                                                pBuffer[MsgIn] = InBuf[InBufInPtr][InBufOutCnt];\
                                                MsgIn++;\
                                                InBufOutCnt++;\
                                                InCnt--;\
                                              }\
                                              if (LengthSize == MsgIn)\
                                              {\
                                                if (2 == LengthSize)\
                                                {\
                                                  FullRxLength   = pBuffer[1];\
                                                  FullRxLength <<= 8;\
                                                  FullRxLength  |= pBuffer[0];\
                                                  /* Remove Length when in strean mode */\
                                                  MsgIn          = 0;\
                                                }\
                                                else\
                                                {\
                                                  FullRxLength = pBuffer[0];\
                                                }\
                                                RemainingLength = FullRxLength;\
                                              }\
                                              else\
                                              {\
                                                /* Length still not received */\
                                                FullRxLength = 0;\
                                              }\
                                            }\
                                            if (FullRxLength)\
                                            {\
                                              /* Incomming msg in progress */\
                                              /* room for bytes? */\
                                              if (InCnt >= RemainingLength)\
                                              {\
                                                /* Remaining msg bytes are in the buffer   */\
                                                /* Can remaining byte be stored in buffer? */\
                                                if ((MsgIn + RemainingLength) <= SIZE_OF_INBUF)\
                                                {\
                                                  /* All bytes can be stored */\
                                                  for (Cnt = 0; Cnt < RemainingLength; Cnt++)\
                                                  {\
                                                    pBuffer[MsgIn] = InBuf[InBufInPtr][InBufOutCnt];\
                                                    MsgIn++;\
                                                    InBufOutCnt++;\
                                                  }\
                                                  *pByteCnt       = MsgIn;\
                                                  *pToGo          = 0;\
                                                  FullRxLength    = 0;\
                                                  RemainingLength = 0;\
                                                  MsgIn           = 0;\
                                                }\
                                                else\
                                                {\
                                                  for (Cnt = 0; MsgIn < SIZE_OF_INBUF; Cnt++)\
                                                  {\
                                                    pBuffer[MsgIn] = InBuf[InBufInPtr][InBufOutCnt];\
                                                    MsgIn++;\
                                                    InBufOutCnt++;\
                                                  }\
                                                  *pByteCnt        = SIZE_OF_INBUF;\
                                                  RemainingLength -= Cnt;\
                                                  *pToGo           = RemainingLength;\
                                                  MsgIn            = 0;\
                                                }\
                                              }\
                                              else\
                                              {\
                                                if ((InCnt + MsgIn) < SIZE_OF_INBUF)\
                                                {\
                                                  /* Received bytes do not fill up the buffer */\
                                                  for (Cnt = 0; Cnt < InCnt; Cnt++)\
                                                  {\
                                                    pBuffer[MsgIn] = InBuf[InBufInPtr][InBufOutCnt];\
                                                    MsgIn++;\
                                                    InBufOutCnt++;\
                                                  }\
                                                  RemainingLength -= InCnt;\
                                                }\
                                                else\
                                                {\
                                                  /* Received bytes fill up the buffer */\
                                                  for (Cnt = 0; MsgIn < SIZE_OF_INBUF; Cnt++)\
                                                  {\
                                                    pBuffer[MsgIn] = InBuf[InBufInPtr][InBufOutCnt];\
                                                    MsgIn++;\
                                                    InBufOutCnt++;\
                                                  }\
                                                  *pByteCnt        = SIZE_OF_INBUF;\
                                                  RemainingLength -= Cnt; /* Only substract no removed */\
                                                  *pToGo           = RemainingLength;\
                                                  MsgIn            = 0;\
                                                }\
                                              }\
                                            }\
                                          }\
                                          if ((*AT91C_US1_RNCR == 0) && (SIZE_OF_INBUF == InBufOutCnt))\
                                          {\
                                            InBufOutCnt     = 0;\
                                            *AT91C_US1_RNPR = (unsigned int)InBufPtrs[InBufInPtr];\
                                            *AT91C_US1_RNCR = SIZE_OF_INBUF;\
                                            InBufInPtr      = (InBufInPtr + 1) % NO_OF_INBUFFERS;\
                                          }\
                                        }

#define BTExit                          {\
                                          *AT91C_PMC_PCDR = PER_ID7_UART_1;        /* Disable PMC clock for UART 1*/\
                                          *AT91C_US1_IDR  = AT91C_US_TIMEOUT;      /* Disable interrupt on timeout */\
                                          *AT91C_AIC_IDCR = UART1_INQ;             /* Disable PIO interrupt */\
                                          *AT91C_AIC_ICCR = UART1_INQ;             /* Clear interrupt register */\
                                        }


#endif

#ifdef    PCWIN

#endif
