a serial library to communicate with pebble time's smart strap interface
Dependents: xadow_smartstrap_for_pebble
mbedPebbleSerial.cpp
- Committer:
- KillingJacky
- Date:
- 2015-11-04
- Revision:
- 0:e4dad9e53f06
File content as of revision 0:e4dad9e53f06:
/* * This is an Arduino library wrapper around the PebbleSerial library. */ #include "mbed.h" #include "BufferedSerial.h" #include "mbedPebbleSerial.h" static uint8_t *s_buffer; static size_t s_buffer_length; static uint8_t s_pin; extern BufferedSerial serial; #define _BV(bit) (1<<(bit)) #define cbi(sfr, bit) ((sfr) &= ~_BV(bit)) #define sbi(sfr, bit) ((sfr) |= _BV(bit)) static void board_begin(void) { } static void board_set_tx_enabled(bool enabled) { if (enabled) { // enable transmitter sbi(LPC_USART->TER, 7); // disable receiver sbi(LPC_USART->RS485CTRL, 1); } else { // disable transmitter cbi(LPC_USART->TER, 7); // enable receiver cbi(LPC_USART->RS485CTRL, 1); } } static void board_set_even_parity(bool enabled) { if (enabled) { sbi(LPC_USART->LCR, 3); sbi(LPC_USART->LCR, 4); } else { cbi(LPC_USART->LCR, 3); cbi(LPC_USART->LCR, 4); } } static void board_flush_uart() { while (serial._txbuf.available()); while (!(LPC_USART->LSR & _BV(5))); } static void prv_cmd_cb(SmartstrapCmd cmd, uint32_t arg) { switch (cmd) { case SmartstrapCmdSetBaudRate: serial.baud(arg); break; case SmartstrapCmdSetTxEnabled: if (!arg) board_flush_uart(); board_set_tx_enabled(arg); break; case SmartstrapCmdWriteByte: serial.putc((uint8_t)arg); break; case SmartstrapCmdWriteBreak: board_set_even_parity(true); serial.putc((uint8_t)0); // need to flush before changing parity board_flush_uart(); board_set_even_parity(false); break; default: break; } } static void prv_begin(uint8_t *buffer, size_t length, Baud baud, const uint16_t *services, uint8_t num_services) { s_buffer = buffer; s_buffer_length = length; pebble_init(prv_cmd_cb, (PebbleBaud)baud, services, num_services); pebble_prepare_for_read(s_buffer, s_buffer_length); } void mbedPebbleSerial::begin(uint8_t *buffer, size_t length, Baud baud, const uint16_t *services, uint8_t num_services) { prv_begin(buffer, length, baud, services, num_services); } static int prv_available_bytes(void) { return serial.readable(); } static uint8_t prv_read_byte(void) { return (uint8_t)serial.getc(); } bool mbedPebbleSerial::feed(uint16_t *service_id, uint16_t *attribute_id, size_t *length, RequestType *type) { SmartstrapRequestType request_type; bool did_feed = false; while (prv_available_bytes()) { did_feed = true; if (pebble_handle_byte(prv_read_byte(), service_id, attribute_id, length, &request_type, us_ticker_read()/1000)) { // we have a full frame pebble_prepare_for_read(s_buffer, s_buffer_length); switch (request_type) { case SmartstrapRequestTypeRead: *type = RequestTypeRead; break; case SmartstrapRequestTypeWrite: *type = RequestTypeWrite; break; case SmartstrapRequestTypeWriteRead: *type = RequestTypeWriteRead; break; default: break; } return true; } } if (!did_feed) { // allow the pebble code to dicsonnect if we haven't gotten any messages recently pebble_is_connected(us_ticker_read()/1000); } return false; } bool mbedPebbleSerial::write(bool success, const uint8_t *payload, size_t length) { return pebble_write(success, payload, length); } void mbedPebbleSerial::notify(uint16_t service_id, uint16_t attribute_id) { pebble_notify(service_id, attribute_id); } bool mbedPebbleSerial::is_connected(void) { return pebble_is_connected(us_ticker_read()/1000); }