'**************************************************************** '* Name : Orb_Xmitter_v5.pbp * '* Author : Pete Burnight * '* Notice : Copyright (c) 2007 Central Coast Software * '* : To be released under GNU Public License * '* Date : 3/6/07 * '* Version : 4.1 * '* Notes : v3 Found flaw in Tx code - we now flush before send '* : v4 adding Log On/Off button - Works GREAT * '* : v5 Sending a variety of commands * '**************************************************************** @ Device HS_OSC ' High Speed Crystal @ Device WDT_ON ' Watch Dog timer ON @ Device PWRT_ON ' Power Reset timer ON @ Device BOD_ON ' Brown out Protection ON @ Device LVP_OFF ' Low voltage programming capability @ Device CPD_OFF ' Code Protection OFF DEFINE __16F876A 1 DEFINE OSC 20 '----- Debug Definitions ---------------------------- DEFINE DEBUG_REG PORTC DEFINE DEBUG_BIT 6 DEFINE DEBUG_BAUD 9600 DEFINE DEBUG_MODE 0 DEFINE HSER_BAUD 9600 'DEFINE HSER_RCSTA 90h DEFINE HSER_TXSTA 24h DEFINE HSER_SPBRG 129 ' ---------------------------------------------------- ' Connections to MiRF Transceiver pins MiRF_CE VAR PORTC.3 MiRF_CSN VAR PORTC.4 MiRF_SCK VAR PORTC.5 MiRF_MISO VAR PORTA.2 MiRF_MOSI VAR PORTA.3 MiRF_IRQ VAR PORTA.4 ' ---- Command Constants -------------------------------------- SET_SPEED CON $01 SET_STEER CON $02 SET_VELOCITY CON $03 SET_STEER_ANGLE CON $04 SET_VALUE CON $30 SET_VALUE1 CON $31 SET_VALUE2 CON $32 LOG_ON_OFF CON $2A HEART_BEAT CON $8A ' ------------------------------------------------------------- LED VAR PORTA.1 RedLED Var PortC.0 YellowLED VAR PortC.1 GreenLED VAR PortC.2 Buzzer Var PortB.0 Btn1 Var PortB.1 Btn2 Var PortB.2 Btn3 Var PortB.3 Btn4 Var PortB.4 Btn5 Var PortB.5 Btn6 Var PortA.5 A2Dval Var Word PotValue Var Word PortBits Var Byte PrevBits Var Byte BtnBits Var Byte theCmd Var Byte theData Var Word CrntSpeed Var Word CrntSteer Var Word ClockCount Var Word SeqNum Var Byte LogON Var Bit ' ---------------------------------------------------- ' Vars used by the MiRF unit x Var Byte j Var Byte DataArray VAR Byte[8] theStatusByte Var Byte theDataByte Var Byte nBytes Var Byte pipeNum Var Byte Tx_FIFO_Status VAR Byte ' ---------------------------------------------------- Goto InitSeq ' ---------------------------------------------------- include "MiRF_Inc_v4.inc" ' ---------------------------------------------------- Read_Pot: ADCON0 = %10000001 ' Set A/D to Fosc/32, Channel 0, On Read_AD: Pauseus 10 ' Wait for channel to setup ADCON0.2 = 1 ' Start conversion wLoop: Pauseus 5 ' Wait for conversion IF ADCON0.2 = 1 then wLoop A2Dval.HIGHBYTE = ADRESH A2Dval.LowBYTE = ADRESL Return ' ---------------------------------------------------- InitSeq: High LED Pause 100 TRISA = %00110101 TRISB = %00111110 TRISC = %10000000 ADCON1 = %10001110 ' Only channel 0 is Analogue ADCON0 = $80 ' Set A/D to Fosc/32, Channel 0, Off OPTION_REG.7 = 0 ' Turn ON Port-B Pullups PrevBits = 0 CrntSpeed = 0 CrntSteer = 0 SeqNum = 0 LogON = 0 HSerOut [ $FE, 1, "Hi there..." ] Gosub Config_TX Low LED ' ---------------------------------------------------- ButtonLoop: Gosub Read_Pot PotValue = A2Dval - 20 If PotValue.Bit15 then PotValue = 0 PotValue = ((PotValue Min 1000) / 5) - 100 ' range now [-100..0..100] HSerOut [ $FE, $80, "Value: ", SDec PotValue, " " ] HSerOut [ $FE, $94, "Speed: ", SDec CrntSpeed, " " ] HSerOut [ $FE, $D4, "Steer: ", SDec CrntSteer, " " ] If LogON Then HSerOut [ $FE, $C0, " -- Log ON -- " ] Else HSerOut [ $FE, $C0, "Log OFF " ] EndIf PortBits = PortB ' De-bounce buttons - prevent Auto-repeat PortBits.0 = PortA.5 ' port B has pullups - High means no button Pause 10 ' Button press pulls Port B lines LOW BtnBits = PortB BtnBits.0 = PortA.5 ' A5 is Olimex On-board button PortBits = PortBits & BtnBits PortBits = PortBits & %00111111 BtnBits = BtnBits ^ PrevBits ' XOR with Prev Bits BtnBits = BtnBits & PrevBits ' BtnBits should now have valid keypresses If BtnBits.0 Then ' Button on the Olimex Board itself. theCmd = LOG_ON_OFF If LogON then ' if current state is ON, turn it OFF theData = 0 LogON = 0 Else theData = 1 LogON = 1 EndIf Gosub Send_Command EndIf If BtnBits.1 Then CrntSpeed = PotValue theCmd = SET_SPEED ' caution - speed & velo are mixed here theData = CrntSpeed Gosub Send_Command EndIf If BtnBits.2 Then CrntSpeed = 0 theCmd = SET_SPEED theData = CrntSpeed Gosub Send_Command EndIf If BtnBits.3 Then CrntSpeed = CrntSpeed - 5 theCmd = SET_SPEED theData = CrntSpeed Gosub Send_Command EndIf ' ----- If BtnBits.4 Then ' Outside Red Button CrntSteer = PotValue theCmd = SET_VALUE2 theData = CrntSteer Gosub Send_Command EndIf If BtnBits.5 Then ' Inside Red Button CrntSteer = PotValue theCmd = SET_VALUE1 theData = CrntSteer Gosub Send_Command EndIf ' ----- Pause 100 PrevBits = PortBits ClockCount = ClockCount + 1 If ClockCount > 10 Then ' about once per second High LED Pause 10 Low LED ClockCount = 0 EndIf if (MiRF_IRQ == 0) Then ' Handle all IRQs Gosub Handle_MiRF_IRQ EndIf goto ButtonLoop ' ---------------------------------------------------------------------------------------------------------------------------------------- ' Send out the data in DataArray Send_Command: ' HSerOut ["--Send Cmd: ", Dec theCmd, " ", SDec theData, 13,13] FreqOut Buzzer, 20, 200 ClockCount = 0 DataArray[0] = theCmd DataArray[1] = theData.HighByte DataArray[2] = theData.LowByte DataArray[3] = SeqNum SeqNum = SeqNum + 1 ' Goto Transmit_Data ' RETURN Check_FIFO_Status: theCmd = READ_REG + FIFO_STATUS Gosub SPI_Read Tx_FIFO_Status = theDataByte ' Debug " FIFO Status: $", HEX Tx_FIFO_Status If Tx_FIFO_Status.Bit4 Then ' Debug " Tx FIFO is Empty - Xmit new data...", 13 Goto Transmit_Data ' Tx FIFO is empty EndIf ' Debug "Tx FIFO NOT Empty... Flush it!", 13 High Buzzer Pause 40 Low Buzzer MiRF_CSN = 0 theDataByte = FLUSH_TX ' --- theCmd Gosub SPI_Rw_Byte MiRF_CSN = 1 Goto Check_FIFO_Status Transmit_Data: ' clear TX fifo ------------------------------------------------------- ' the data sheet says that this is supposed to come up 0 after POR, ' but that doesn't seem to be the case ' MiRF_CSN = 0 ' theDataByte = FLUSH_TX ' --- theCmd ' Gosub SPI_Rw_Byte ' MiRF_CSN = 1 theCmd = WR_TX_PLOAD ' --- 4 Byte payload ---- nBytes = 4 Gosub SPI_Write_Buf MiRF_CE = 1 ' Pulse CE to start transmission Pauseus 15 ' 10 us min MiRF_CE = 0 RETURN ' ---------------------------------------------------------------------------------------------------------------------------------------- ' ---------------------------------------------------------------------------------------------------------------------------------- Config_TX: MiRF_CE = 0 Gosub Setup_MiRF_Address theCmd = WRITE_REG + TX_ADDR ' --- Setup TX Addresss nBytes = 5 Gosub SPI_Write_Buf theCmd = WRITE_REG + RX_ADDR_P0 ' --- Setup RX Addresss for Auto-Ack nBytes = 5 Gosub SPI_Write_Buf ' Gosub Setup_Packet_Data ' theCmd = WR_TX_PLOAD ' --- Load TX payload ' nBytes = 8 ' Gosub SPI_Write_Buf MiRF_CSN = 0 theDataByte = FLUSH_TX ' --- theCmd Gosub SPI_Rw_Byte MiRF_CSN = 1 theCmd = WRITE_REG + EN_AA theData = $01 ' Enable Auto Ack Pipe0 Gosub SPI_Rw_Reg theCmd = WRITE_REG + EN_RXADDR theData = $01 ' Enable Pipe0 Gosub SPI_Rw_Reg theCmd = WRITE_REG + SETUP_RETR theData = $0A ' xx us + 86 us, 10 retries... Gosub SPI_Rw_Reg theCmd = WRITE_REG + RF_CH theData = 40 ' Select RF Channel 40 Gosub SPI_Rw_Reg theCmd = WRITE_REG + RF_SETUP theData = $0F ' TX_PWR: 0dBm, DataRate: 2Mbps, LNA:HCURR Gosub SPI_Rw_Reg theCmd = WRITE_REG + CONFIG ' Set PWR_UP bit, enable CRC theData = $0E ' Prim:TX, MAX_R & TX_DS enabled Gosub SPI_Rw_Reg RETURN ' ---------------------------------------------------------------------------------------------------------------------------------------- Handle_MiRF_IRQ: theCmd = WRITE_REG + STATUS_REG theData = $70 ' Read Status and clear IRQ flags Gosub SPI_Rw_Reg ' Debug "Status Byte: ", dec theStatusByte, 13 If (theStatusByte & MAX_RT) Then ' Indicates max #of retransmit interrupt for x = 1 to 4 HIGH RedLED Pause 20 Low RedLED Pause 20 Next x EndIf If (theStatusByte & TX_DS) Then ' Indicates TX data succsessfully sent HIGH GreenLED Pause 20 Low GreenLED EndIf If (theStatusByte & RX_DR) Then ' in Rx Mode - check data Received pipeNum = ($07 & (theStatusByte >> 1)) ' Debug "Data Rcv IRQ - PipeNum: ", Dec pipeNum, 13 theCmd = READ_REG + Rx_PW_P0 + pipeNum Gosub SPI_Read nBytes = theDataByte ' Debug "nBytes in Packet: ", Dec nBytes, 13 theCmd = RD_RX_PLOAD Gosub SPI_Read_Buf EndIf RETURN ' ---------------------------------------------------------------------------------------------------------------------------------------- END