Advertisement
Guest User

Untitled

a guest
Jun 18th, 2019
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 14.40 KB | None | 0 0
  1. /** DEXDRIP Translator:
  2.   == Description ==
  3.   The app uses the radio_queue libray to receive packets.  It does not
  4.   transmit any packets.
  5.  
  6.   The output from this app takes the following format:
  7.   RAWREADING TRANSMITTERBATTERY WIXELBATTERY
  8.  
  9.   The green LED indicates that data was just sent
  10.  
  11.   PLEASE BE SURE TO SET YOUR TRANSMITTER ID BELOW
  12.  
  13.   == Parameters ==
  14. radio_channel: See description in radio_link.h.
  15. */
  16.  
  17.  
  18. /** Dependencies **************************************************************/
  19. /*#define DEBUG*/
  20. #include <cc2511_map.h>
  21. #include <board.h>
  22. #include <random.h>
  23. #include <time.h>
  24. #include <usb.h>
  25. #include <usb_com.h>
  26. #include <radio_registers.h>
  27. #include <radio_queue.h>
  28. #include <gpio.h>
  29. #include <uart1.h>
  30. #include <stdio.h>
  31. #include <string.h>
  32. #include <ctype.h>
  33. #include <adc.h>
  34.  
  35. //////////////////////////////////////////////////////////////////////////////////////////////////////
  36. //////////////////////////////////////////////////////////////////////////////////////////////////////
  37. //////////////////////////////////////////////////////////////////////////////////////////////////////
  38. //////////////////////////////////////////////////////////////////////////////////////////////////////
  39. //                                                                                                  //
  40. //                           SET THESE VARIABLES TO MEET YOUR NEEDS                                 //
  41. //                                   1 = TRUE       0 = FALSE                                       //
  42. //                                                                                                  //
  43.   static XDATA const char transmitter_id[] = "8815F";                                               //
  44. //                                                                                                  //
  45.   static volatile BIT only_listen_for_my_transmitter = 1;                                           //
  46. // 1 is recommended                                                                                 //
  47. //                                                                                                  //
  48.   static volatile BIT status_lights = 1;                                                            //
  49. // if status_lights = 1; the yellow light flashes while actively scanning                           //
  50. // if a light is flashing for more than 10 minutes straight, it may not be picking up your dex      //
  51. //                                                                                                  //
  52. //                                                                                                  //
  53. //..................................................................................................//
  54. //////////////////////////////////////////////////////////////////////////////////////////////////////
  55. //////////////////////////////////////////////////////////////////////////////////////////////////////
  56. //////////////////////////////////////////////////////////////////////////////////////////////////////
  57. //////////////////////////////////////////////////////////////////////////////////////////////////////
  58. static XDATA volatile int start_channel = 0;
  59. uint32 XDATA asciiToDexcomSrc(char *addr);
  60. uint32 XDATA getSrcValue(char srcVal);
  61. volatile uint32 dex_tx_id;
  62. #define NUM_CHANNELS        (4)
  63. static int8 fOffset[NUM_CHANNELS] = {0xCE,0xD5,0xE6,0xE5};
  64. static XDATA int8 defaultfOffset[NUM_CHANNELS] = {0xCE,0xD5,0xE6,0xE5};
  65. static uint8 nChannels[NUM_CHANNELS] = { 0, 100, 199, 209 };
  66. static uint32 waitTimes[NUM_CHANNELS] = { 30000, 700, 700, 700 };
  67. //Now lets try to crank down the channel 1 wait time, if we can 5000 works but it wont catch channel 4 ever
  68. static uint32 delayedWaitTimes[NUM_CHANNELS] = { 0, 700, 700, 700 };
  69. BIT needsTimingCalibration = 1;
  70. BIT usbEnabled = 1;
  71. static uint8 save_IEN0;
  72. static uint8 save_IEN1;
  73. static uint8 save_IEN2;
  74. unsigned char XDATA PM2_BUF[7] = {0x06,0x06,0x06,0x06,0x06,0x06,0x04};
  75. unsigned char XDATA dmaDesc[8] = {0x00,0x00,0xDF,0xBE,0x00,0x07,0x20,0x42};
  76.  
  77. typedef struct _Dexcom_packet {
  78.     uint8   len;
  79.     uint32  dest_addr;
  80.     uint32  src_addr;
  81.     uint8   port;
  82.     uint8   device_info;
  83.     uint8   txId;
  84.     uint16  raw;
  85.     uint16  filtered;
  86.     uint8   battery;
  87.     uint8   unknown;
  88.     uint8   checksum;
  89.     int8    RSSI;
  90.     uint8   LQI;
  91. } Dexcom_packet;
  92.  
  93. void sleepInit(void) {
  94.    WORIRQ  |= (1<<4);
  95. }
  96.  
  97. ISR(ST, 1) {
  98.     IRCON &= 0x7F;
  99.     WORIRQ &= 0xFE;
  100.     SLEEP &= 0xFC;
  101. }
  102.  
  103. void switchToRCOSC(void) {
  104.     SLEEP &= ~0x04;
  105.     while ( ! (SLEEP & 0x20) );
  106.     CLKCON = (CLKCON & ~0x07) | 0x40 | 0x01;
  107.     while ( !(CLKCON & 0x40) );
  108.     SLEEP |= 0x04;
  109. }
  110.  
  111. void uartEnable() {
  112.     U1UCR |= 0x40; //CTS/RTS ON
  113.     delayMs(1000);
  114. }
  115.  
  116. void uartDisable() {
  117.     delayMs(1000);
  118.     U1UCR &= ~0x40; //CTS/RTS Off
  119.     U1CSR &= ~0x40; // Recevier disable
  120. }
  121.  
  122. void blink_yellow_led() {
  123.     if(status_lights) {
  124.         LED_YELLOW(((getMs()/500) % 2));//Blink half seconds
  125.     }
  126. }
  127.  
  128. void blink_red_led() {
  129.     if(status_lights) {
  130.         LED_RED(((getMs()/500) % 2));//Blink half seconds
  131.     }
  132. }
  133.  
  134. int8 getPacketRSSI(Dexcom_packet* p) {
  135.     return (p->RSSI/2)-73;
  136. }
  137.  
  138. uint8 getPacketPassedChecksum(Dexcom_packet* p) {
  139.     return ((p->LQI & 0x80)==0x80) ? 1:0;
  140. }
  141.  
  142. uint8 bit_reverse_byte(uint8 in) {
  143.     uint8 XDATA bRet = 0;
  144.     if(in & 0x01)
  145.         bRet |= 0x80;
  146.     if(in & 0x02)
  147.         bRet |= 0x40;
  148.     if(in & 0x04)
  149.         bRet |= 0x20;
  150.     if(in & 0x08)
  151.         bRet |= 0x10;
  152.     if(in & 0x10)
  153.         bRet |= 0x08;
  154.     if(in & 0x20)
  155.         bRet |= 0x04;
  156.     if(in & 0x40)
  157.         bRet |= 0x02;
  158.     if(in & 0x80)
  159.         bRet |= 0x01;
  160.     return bRet;
  161. }
  162.  
  163. uint8 min8(uint8 a, uint8 b) {
  164.     if(a < b) return a;
  165.     return b;
  166. }
  167.  
  168. void bit_reverse_bytes(uint8* buf, uint8 nLen) {
  169.     uint8 XDATA i = 0;
  170.     for(; i < nLen; i++) {
  171.         buf[i] = bit_reverse_byte(buf[i]);
  172.     }
  173. }
  174.  
  175. uint32 dex_num_decoder(uint16 usShortFloat) {
  176.     uint16 XDATA usReversed = usShortFloat;
  177.     uint8 XDATA usExponent = 0;
  178.     uint32 XDATA usMantissa = 0;
  179.     bit_reverse_bytes((uint8*)&usReversed, 2);
  180.     usExponent = ((usReversed & 0xE000) >> 13);
  181.     usMantissa = (usReversed & 0x1FFF);
  182.     return usMantissa << usExponent;
  183. }
  184.  
  185. char XDATA SrcNameTable[32] = { '0', '1', '2', '3', '4', '5', '6', '7',
  186.                           '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
  187.                           'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P',
  188.                           'Q', 'R', 'S', 'T', 'U', 'W', 'X', 'Y' };
  189.  
  190. void dexcom_src_to_ascii(uint32 src, char addr[6]) {
  191.     addr[0] = SrcNameTable[(src >> 20) & 0x1F];
  192.     addr[1] = SrcNameTable[(src >> 15) & 0x1F];
  193.     addr[2] = SrcNameTable[(src >> 10) & 0x1F];
  194.     addr[3] = SrcNameTable[(src >> 5) & 0x1F];
  195.     addr[4] = SrcNameTable[(src >> 0) & 0x1F];
  196.     addr[5] = 0;
  197. }
  198.  
  199. void doServices() {
  200.     if(usbPowerPresent()) {
  201.         boardService();
  202.         usbComService();
  203.     }
  204. }
  205.  
  206. void initUart1() {
  207.     uart1Init();
  208.     uart1SetBaudRate(9600);
  209. }
  210.  
  211. uint32 asciiToDexcomSrc(char addr[6]) {
  212.     uint32 XDATA src = 0;
  213.     src |= (getSrcValue(addr[0]) << 20);
  214.     src |= (getSrcValue(addr[1]) << 15);
  215.     src |= (getSrcValue(addr[2]) << 10);
  216.     src |= (getSrcValue(addr[3]) << 5);
  217.     src |= getSrcValue(addr[4]);
  218.     return src;
  219. }
  220.  
  221. uint32 getSrcValue(char srcVal) {
  222.     uint8 i = 0;
  223.     for(i = 0; i < 32; i++) {
  224.         if (SrcNameTable[i]==srcVal) break;
  225.     }
  226.     return i & 0xFF;
  227. }
  228. void print_packet(Dexcom_packet* pPkt) {
  229.     uartEnable();
  230.     printf("%lu %hhu %d", dex_num_decoder(pPkt->raw), pPkt->battery, adcConvertToMillivolts(adcRead(0)));
  231.     uartDisable();
  232. }
  233.  
  234. void makeAllOutputs() {
  235.     int XDATA i;
  236.     for (i=1; i < 16; i++) { // in the future, this should be set to only the channels being used for output, and add the one for input
  237.         setDigitalOutput(i, LOW);
  238.     }
  239. }
  240. void makeAllOutputsLow() {
  241.     int XDATA i;
  242.     for (i=0; i < 16; i++) {
  243.         setDigitalOutput(i, LOW);
  244.     }
  245. }
  246.  
  247. void rest_offsets() {
  248.     int i;
  249.     for(i=0; i<4; i++) {
  250.         fOffset[i] = defaultfOffset[i];
  251.     }
  252. }
  253.  
  254. void killWithWatchdog() {
  255.     WDCTL = (WDCTL & ~0x03) | 0x00;
  256.     WDCTL = (WDCTL & ~0x04) | 0x08;
  257. }
  258.  
  259. void goToSleep (uint32 seconds) {
  260.     adcSetMillivoltCalibration(adcReadVddMillivolts());
  261.     makeAllOutputsLow();
  262.  
  263.     if(!usbPowerPresent()){
  264.         unsigned char temp;
  265.         unsigned char storedDescHigh, storedDescLow;
  266.         BIT storedDma0Armed;
  267.         unsigned char storedIEN0, storedIEN1, storedIEN2;
  268.  
  269.         uint8 savedPICTL = PICTL;
  270.         BIT savedP0IE = P0IE;
  271.         uint8 savedP0SEL = P0SEL;
  272.         uint8 savedP0DIR = P0DIR;
  273.         uint8 savedP1SEL = P1SEL;
  274.         uint8 savedP1DIR = P1DIR;
  275.  
  276.         sleepInit();
  277.  
  278.         disableUsbPullup();
  279.         usbDeviceState = USB_STATE_DETACHED;
  280.         usbEnabled = 0;
  281.         SLEEP &= ~(1<<7);
  282.  
  283.         WORCTRL |= 0x03; // 2^5 periods
  284.         switchToRCOSC();
  285.  
  286.         storedDescHigh = DMA0CFGH;
  287.         storedDescLow = DMA0CFGL;
  288.         storedDma0Armed = DMAARM & 0x01;
  289.         DMAARM |= 0x81;
  290.         dmaDesc[0] = ((unsigned int)& PM2_BUF) >> 8;
  291.         dmaDesc[1] = (unsigned int)& PM2_BUF;
  292.  
  293.         DMA0CFGH = ((unsigned int)&dmaDesc) >> 8;
  294.         DMA0CFGL = (unsigned int)&dmaDesc;
  295.         DMAARM = 0x01;
  296.  
  297.         // save enabled interrupts
  298.         storedIEN0 = IEN0;
  299.         storedIEN1 = IEN1;
  300.         storedIEN2 = IEN2;
  301.  
  302.         //enable sleep timer interrupt
  303.         IEN0 |= 0xA0;
  304.  
  305.         //disable all interrupts except the sleep timer
  306.         IEN0 &= 0xA0;
  307.         IEN1 &= ~0x3F;
  308.         IEN2 &= ~0x3F;
  309.  
  310.         WORCTRL |= 0x04;  // Reset
  311.         temp = WORTIME0;
  312.         while(temp == WORTIME0) {};
  313.         WOREVT1 = seconds >> 8;
  314.         WOREVT0 = seconds;
  315.  
  316.         temp = WORTIME0;
  317.         while(temp == WORTIME0) {};
  318.  
  319.         MEMCTR |= 0x02;
  320.         SLEEP = 0x06;
  321.         __asm nop __endasm;
  322.         __asm nop __endasm;
  323.         __asm nop __endasm;
  324.         if(SLEEP & 0x03){
  325.             __asm mov 0xD7, #0x01 __endasm;
  326.             __asm nop __endasm;
  327.             __asm orl 0x87, #0x01 __endasm;
  328.             __asm nop __endasm;
  329.         }
  330.         IEN0 = storedIEN0;
  331.         IEN1 = storedIEN1;
  332.         IEN2 = storedIEN2;
  333.         DMA0CFGH = storedDescHigh;
  334.         DMA0CFGL = storedDescLow;
  335.         if(storedDma0Armed){
  336.             DMAARM |= 0x01;
  337.         }
  338.         // Switch back to high speed
  339.         boardClockInit();
  340.  
  341.         PICTL = savedPICTL;
  342.         P0IE = savedP0IE;
  343.         P0SEL = savedP0SEL;
  344.         P0DIR = savedP0DIR;
  345.         P1SEL = savedP1SEL;
  346.         P1DIR = savedP1DIR;
  347.         USBPOW = 1;
  348.         USBCIE = 0b0111;
  349.     } else {
  350.         uint32 start_waiting = getMs();
  351.         if(!usbEnabled) {
  352.             usbDeviceState = USB_STATE_POWERED;
  353.             enableUsbPullup();
  354.             usbEnabled = 1;
  355.         }
  356.         delayMs(100);
  357.         while((getMs() - start_waiting) < (seconds * 1000)) {
  358.             delayMs(10);
  359.             doServices();
  360.         }
  361.     }
  362.     makeAllOutputs();
  363. }
  364.  
  365. void putchar(char c) {
  366.     uart1TxSendByte(c);
  367.     if (usbPowerPresent()) {
  368.         usbComTxSendByte(c);
  369.     }
  370. }
  371.  
  372. void swap_channel(uint8 channel, uint8 newFSCTRL0) {
  373.     do {
  374.         RFST = 4;   //SIDLE
  375.     } while (MARCSTATE != 0x01);
  376.  
  377.     FSCTRL0 = newFSCTRL0;
  378.     CHANNR = channel;
  379.     RFST = 2;   //RX
  380. }
  381.  
  382. void strobe_radio(int radio_chan) {
  383.     radioMacInit();
  384.     MCSM1 = 0;
  385.     radioMacStrobe();
  386.     swap_channel(nChannels[radio_chan], fOffset[radio_chan]);
  387. }
  388.  
  389. int WaitForPacket(uint16 milliseconds, Dexcom_packet* pkt, uint8 channel) {
  390.     uint32 start = getMs();
  391.     uint8 * packet = 0;
  392.     uint32 i = 0;
  393.     uint32 seven_minutes = 420000;
  394.     int nRet = 0;
  395.     swap_channel(nChannels[channel], fOffset[channel]);
  396.  
  397.     while (!milliseconds || (getMs() - start) < milliseconds) {
  398.         i++;
  399.         if(!(i % 60000)) {
  400.             strobe_radio(channel);
  401.         }
  402.         doServices();
  403.         if((getMs() - start) > seven_minutes) {
  404.             killWithWatchdog();
  405.             delayMs(2000);
  406.         }
  407.         blink_yellow_led();
  408.         if (packet = radioQueueRxCurrentPacket()) {
  409.             uint8 len = packet[0];
  410.             fOffset[channel] += FREQEST;
  411.             memcpy(pkt, packet, min8(len+2, sizeof(Dexcom_packet)));
  412.             if(radioCrcPassed()) {
  413.                 if(pkt->src_addr == dex_tx_id || dex_tx_id == 0 || only_listen_for_my_transmitter == 0) {
  414.                     pkt->txId -= channel;
  415.                     radioQueueRxDoneWithPacket();
  416.                     LED_YELLOW(0);
  417.                     return 1;
  418.                 } else {
  419.                     radioQueueRxDoneWithPacket();
  420.                 }
  421.             } else {
  422.                 radioQueueRxDoneWithPacket();
  423.                 LED_YELLOW(0);
  424.                 return 0;
  425.             }
  426.         }
  427.     }
  428.     LED_YELLOW(0);
  429.     return nRet;
  430. }
  431.  
  432. uint32 delayFor(int wait_chan) {
  433.     if(needsTimingCalibration) {
  434.         return delayedWaitTimes[wait_chan];
  435.     }
  436.     return waitTimes[wait_chan];
  437. }
  438.  
  439. BIT get_packet(Dexcom_packet* pPkt) {
  440.     int nChannel = 0;
  441.     for(nChannel = start_channel; nChannel < NUM_CHANNELS; nChannel++) {
  442.         switch(WaitForPacket(delayFor(nChannel), pPkt, nChannel)) {
  443.         case 1:
  444.             needsTimingCalibration = 0;
  445.             return 1;
  446.         case 0:
  447.             continue;
  448.         }
  449.     }
  450.     needsTimingCalibration = 1;
  451.     killWithWatchdog();
  452.     delayMs(2000);
  453.     return 0;
  454. }
  455.  
  456. void setADCInputs() {
  457.     P0INP=0; //set pull resistors on pins 0_0 - 0_5 to low
  458. }
  459.  
  460. void configBt() {
  461.     uartEnable();
  462.     printf("AT+NAMEDexDrip");
  463.     uartDisable();
  464. }
  465.  
  466. void main() {
  467.     systemInit();
  468.     initUart1();
  469.     P1DIR |= 0x08; // RTS
  470.     sleepInit();
  471.  
  472.     makeAllOutputs();
  473.     setADCInputs();
  474.  
  475.     delayMs(1000);
  476.     configBt();
  477.     dex_tx_id= asciiToDexcomSrc(transmitter_id);
  478.     delayMs(1000);
  479.  
  480.     radioQueueInit();
  481.     radioQueueAllowCrcErrors = 1;
  482.     MCSM1 = 0;
  483.  
  484.     while(1) {
  485.         Dexcom_packet Pkt;
  486.         memset(&Pkt, 0, sizeof(Dexcom_packet));
  487.         boardService();
  488.  
  489.         if(get_packet(&Pkt)) {
  490.             print_packet(&Pkt);
  491.         }
  492.  
  493.         RFST = 4;
  494.         delayMs(100);
  495.  
  496.         radioMacSleep();
  497.         goToSleep(280); // Reduce this until we are just on the cusp of missing on the first channels
  498.         radioMacResume();
  499.  
  500.         MCSM1 = 0;
  501.         radioMacStrobe();
  502.     }
  503. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement