a serial library to communicate with pebble time's smart strap interface

Dependents:   xadow_smartstrap_for_pebble

Committer:
KillingJacky
Date:
Wed Nov 04 09:58:41 2015 +0000
Revision:
0:e4dad9e53f06
initial commit;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
KillingJacky 0:e4dad9e53f06 1 /*
KillingJacky 0:e4dad9e53f06 2 * This is an Arduino library wrapper around the PebbleSerial library.
KillingJacky 0:e4dad9e53f06 3 */
KillingJacky 0:e4dad9e53f06 4 #include "mbed.h"
KillingJacky 0:e4dad9e53f06 5 #include "BufferedSerial.h"
KillingJacky 0:e4dad9e53f06 6 #include "mbedPebbleSerial.h"
KillingJacky 0:e4dad9e53f06 7
KillingJacky 0:e4dad9e53f06 8 static uint8_t *s_buffer;
KillingJacky 0:e4dad9e53f06 9 static size_t s_buffer_length;
KillingJacky 0:e4dad9e53f06 10 static uint8_t s_pin;
KillingJacky 0:e4dad9e53f06 11
KillingJacky 0:e4dad9e53f06 12 extern BufferedSerial serial;
KillingJacky 0:e4dad9e53f06 13
KillingJacky 0:e4dad9e53f06 14 #define _BV(bit) (1<<(bit))
KillingJacky 0:e4dad9e53f06 15 #define cbi(sfr, bit) ((sfr) &= ~_BV(bit))
KillingJacky 0:e4dad9e53f06 16 #define sbi(sfr, bit) ((sfr) |= _BV(bit))
KillingJacky 0:e4dad9e53f06 17
KillingJacky 0:e4dad9e53f06 18
KillingJacky 0:e4dad9e53f06 19 static void board_begin(void) {
KillingJacky 0:e4dad9e53f06 20 }
KillingJacky 0:e4dad9e53f06 21
KillingJacky 0:e4dad9e53f06 22 static void board_set_tx_enabled(bool enabled) {
KillingJacky 0:e4dad9e53f06 23 if (enabled) {
KillingJacky 0:e4dad9e53f06 24 // enable transmitter
KillingJacky 0:e4dad9e53f06 25 sbi(LPC_USART->TER, 7);
KillingJacky 0:e4dad9e53f06 26 // disable receiver
KillingJacky 0:e4dad9e53f06 27 sbi(LPC_USART->RS485CTRL, 1);
KillingJacky 0:e4dad9e53f06 28 } else {
KillingJacky 0:e4dad9e53f06 29 // disable transmitter
KillingJacky 0:e4dad9e53f06 30 cbi(LPC_USART->TER, 7);
KillingJacky 0:e4dad9e53f06 31 // enable receiver
KillingJacky 0:e4dad9e53f06 32 cbi(LPC_USART->RS485CTRL, 1);
KillingJacky 0:e4dad9e53f06 33 }
KillingJacky 0:e4dad9e53f06 34 }
KillingJacky 0:e4dad9e53f06 35
KillingJacky 0:e4dad9e53f06 36 static void board_set_even_parity(bool enabled) {
KillingJacky 0:e4dad9e53f06 37 if (enabled) {
KillingJacky 0:e4dad9e53f06 38 sbi(LPC_USART->LCR, 3);
KillingJacky 0:e4dad9e53f06 39 sbi(LPC_USART->LCR, 4);
KillingJacky 0:e4dad9e53f06 40 } else {
KillingJacky 0:e4dad9e53f06 41 cbi(LPC_USART->LCR, 3);
KillingJacky 0:e4dad9e53f06 42 cbi(LPC_USART->LCR, 4);
KillingJacky 0:e4dad9e53f06 43 }
KillingJacky 0:e4dad9e53f06 44 }
KillingJacky 0:e4dad9e53f06 45
KillingJacky 0:e4dad9e53f06 46 static void board_flush_uart()
KillingJacky 0:e4dad9e53f06 47 {
KillingJacky 0:e4dad9e53f06 48 while (serial._txbuf.available());
KillingJacky 0:e4dad9e53f06 49 while (!(LPC_USART->LSR & _BV(5)));
KillingJacky 0:e4dad9e53f06 50 }
KillingJacky 0:e4dad9e53f06 51
KillingJacky 0:e4dad9e53f06 52 static void prv_cmd_cb(SmartstrapCmd cmd, uint32_t arg) {
KillingJacky 0:e4dad9e53f06 53 switch (cmd) {
KillingJacky 0:e4dad9e53f06 54 case SmartstrapCmdSetBaudRate:
KillingJacky 0:e4dad9e53f06 55 serial.baud(arg);
KillingJacky 0:e4dad9e53f06 56 break;
KillingJacky 0:e4dad9e53f06 57 case SmartstrapCmdSetTxEnabled:
KillingJacky 0:e4dad9e53f06 58 if (!arg) board_flush_uart();
KillingJacky 0:e4dad9e53f06 59 board_set_tx_enabled(arg);
KillingJacky 0:e4dad9e53f06 60 break;
KillingJacky 0:e4dad9e53f06 61 case SmartstrapCmdWriteByte:
KillingJacky 0:e4dad9e53f06 62 serial.putc((uint8_t)arg);
KillingJacky 0:e4dad9e53f06 63 break;
KillingJacky 0:e4dad9e53f06 64 case SmartstrapCmdWriteBreak:
KillingJacky 0:e4dad9e53f06 65 board_set_even_parity(true);
KillingJacky 0:e4dad9e53f06 66 serial.putc((uint8_t)0);
KillingJacky 0:e4dad9e53f06 67 // need to flush before changing parity
KillingJacky 0:e4dad9e53f06 68 board_flush_uart();
KillingJacky 0:e4dad9e53f06 69 board_set_even_parity(false);
KillingJacky 0:e4dad9e53f06 70 break;
KillingJacky 0:e4dad9e53f06 71 default:
KillingJacky 0:e4dad9e53f06 72 break;
KillingJacky 0:e4dad9e53f06 73 }
KillingJacky 0:e4dad9e53f06 74 }
KillingJacky 0:e4dad9e53f06 75
KillingJacky 0:e4dad9e53f06 76 static void prv_begin(uint8_t *buffer, size_t length, Baud baud,
KillingJacky 0:e4dad9e53f06 77 const uint16_t *services, uint8_t num_services) {
KillingJacky 0:e4dad9e53f06 78 s_buffer = buffer;
KillingJacky 0:e4dad9e53f06 79 s_buffer_length = length;
KillingJacky 0:e4dad9e53f06 80
KillingJacky 0:e4dad9e53f06 81 pebble_init(prv_cmd_cb, (PebbleBaud)baud, services, num_services);
KillingJacky 0:e4dad9e53f06 82 pebble_prepare_for_read(s_buffer, s_buffer_length);
KillingJacky 0:e4dad9e53f06 83 }
KillingJacky 0:e4dad9e53f06 84
KillingJacky 0:e4dad9e53f06 85 void mbedPebbleSerial::begin(uint8_t *buffer, size_t length, Baud baud,
KillingJacky 0:e4dad9e53f06 86 const uint16_t *services, uint8_t num_services) {
KillingJacky 0:e4dad9e53f06 87 prv_begin(buffer, length, baud, services, num_services);
KillingJacky 0:e4dad9e53f06 88 }
KillingJacky 0:e4dad9e53f06 89
KillingJacky 0:e4dad9e53f06 90 static int prv_available_bytes(void) {
KillingJacky 0:e4dad9e53f06 91 return serial.readable();
KillingJacky 0:e4dad9e53f06 92 }
KillingJacky 0:e4dad9e53f06 93
KillingJacky 0:e4dad9e53f06 94 static uint8_t prv_read_byte(void) {
KillingJacky 0:e4dad9e53f06 95 return (uint8_t)serial.getc();
KillingJacky 0:e4dad9e53f06 96 }
KillingJacky 0:e4dad9e53f06 97
KillingJacky 0:e4dad9e53f06 98 bool mbedPebbleSerial::feed(uint16_t *service_id, uint16_t *attribute_id, size_t *length,
KillingJacky 0:e4dad9e53f06 99 RequestType *type) {
KillingJacky 0:e4dad9e53f06 100 SmartstrapRequestType request_type;
KillingJacky 0:e4dad9e53f06 101 bool did_feed = false;
KillingJacky 0:e4dad9e53f06 102 while (prv_available_bytes()) {
KillingJacky 0:e4dad9e53f06 103 did_feed = true;
KillingJacky 0:e4dad9e53f06 104 if (pebble_handle_byte(prv_read_byte(), service_id, attribute_id, length, &request_type, us_ticker_read()/1000)) {
KillingJacky 0:e4dad9e53f06 105 // we have a full frame
KillingJacky 0:e4dad9e53f06 106 pebble_prepare_for_read(s_buffer, s_buffer_length);
KillingJacky 0:e4dad9e53f06 107 switch (request_type) {
KillingJacky 0:e4dad9e53f06 108 case SmartstrapRequestTypeRead:
KillingJacky 0:e4dad9e53f06 109 *type = RequestTypeRead;
KillingJacky 0:e4dad9e53f06 110 break;
KillingJacky 0:e4dad9e53f06 111 case SmartstrapRequestTypeWrite:
KillingJacky 0:e4dad9e53f06 112 *type = RequestTypeWrite;
KillingJacky 0:e4dad9e53f06 113 break;
KillingJacky 0:e4dad9e53f06 114 case SmartstrapRequestTypeWriteRead:
KillingJacky 0:e4dad9e53f06 115 *type = RequestTypeWriteRead;
KillingJacky 0:e4dad9e53f06 116 break;
KillingJacky 0:e4dad9e53f06 117 default:
KillingJacky 0:e4dad9e53f06 118 break;
KillingJacky 0:e4dad9e53f06 119 }
KillingJacky 0:e4dad9e53f06 120 return true;
KillingJacky 0:e4dad9e53f06 121 }
KillingJacky 0:e4dad9e53f06 122 }
KillingJacky 0:e4dad9e53f06 123
KillingJacky 0:e4dad9e53f06 124 if (!did_feed) {
KillingJacky 0:e4dad9e53f06 125 // allow the pebble code to dicsonnect if we haven't gotten any messages recently
KillingJacky 0:e4dad9e53f06 126 pebble_is_connected(us_ticker_read()/1000);
KillingJacky 0:e4dad9e53f06 127 }
KillingJacky 0:e4dad9e53f06 128 return false;
KillingJacky 0:e4dad9e53f06 129 }
KillingJacky 0:e4dad9e53f06 130
KillingJacky 0:e4dad9e53f06 131 bool mbedPebbleSerial::write(bool success, const uint8_t *payload, size_t length) {
KillingJacky 0:e4dad9e53f06 132 return pebble_write(success, payload, length);
KillingJacky 0:e4dad9e53f06 133 }
KillingJacky 0:e4dad9e53f06 134
KillingJacky 0:e4dad9e53f06 135 void mbedPebbleSerial::notify(uint16_t service_id, uint16_t attribute_id) {
KillingJacky 0:e4dad9e53f06 136 pebble_notify(service_id, attribute_id);
KillingJacky 0:e4dad9e53f06 137 }
KillingJacky 0:e4dad9e53f06 138
KillingJacky 0:e4dad9e53f06 139 bool mbedPebbleSerial::is_connected(void) {
KillingJacky 0:e4dad9e53f06 140 return pebble_is_connected(us_ticker_read()/1000);
KillingJacky 0:e4dad9e53f06 141 }