From b153cbd84327b97c6d1f7eacad52dab79e0c2d7e Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Sun, 12 Aug 2012 23:06:21 +0200 Subject: Created clean new BCM4751 gpsd code that works and prints the read data Signed-off-by: Paul Kocialkowski --- Android.mk | 22 +++- Makefile | 6 - bcm4751_daemon.c | 60 ---------- bcm4751_gpsd.c | 294 +++++++++++++++++++++++++++++++++++++++++++++++++ bcm4751_hal.c | 150 ------------------------- bcm4751_lib.c | 65 ----------- bcm4751_test.c | 265 -------------------------------------------- meif.h | 67 +++++++++++ utils/Makefile | 6 + utils/bcm4751_daemon.c | 60 ++++++++++ utils/bcm4751_hal.c | 150 +++++++++++++++++++++++++ utils/bcm4751_lib.c | 65 +++++++++++ utils/bcm4751_test.c | 265 ++++++++++++++++++++++++++++++++++++++++++++ 13 files changed, 925 insertions(+), 550 deletions(-) delete mode 100644 Makefile delete mode 100644 bcm4751_daemon.c create mode 100644 bcm4751_gpsd.c delete mode 100644 bcm4751_hal.c delete mode 100644 bcm4751_lib.c delete mode 100644 bcm4751_test.c create mode 100644 meif.h create mode 100644 utils/Makefile create mode 100644 utils/bcm4751_daemon.c create mode 100644 utils/bcm4751_hal.c create mode 100644 utils/bcm4751_lib.c create mode 100644 utils/bcm4751_test.c diff --git a/Android.mk b/Android.mk index 5a305a3..eecee6d 100644 --- a/Android.mk +++ b/Android.mk @@ -2,7 +2,7 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) -LOCAL_SRC_FILES := bcm4751_test.c +LOCAL_SRC_FILES := utils/bcm4751_test.c LOCAL_C_INCLUDES += $(LOCAL_PATH)/include LOCAL_SHARED_LIBRARIES := liblog libcutils @@ -15,7 +15,7 @@ include $(BUILD_EXECUTABLE) include $(CLEAR_VARS) -LOCAL_SRC_FILES := bcm4751_hal.c +LOCAL_SRC_FILES := utils/bcm4751_hal.c LOCAL_C_INCLUDES += $(LOCAL_PATH)/include LOCAL_C_INCLUDES += hardware/libhardware/include/ @@ -30,7 +30,7 @@ include $(BUILD_EXECUTABLE) include $(CLEAR_VARS) -LOCAL_SRC_FILES := bcm4751_daemon.c +LOCAL_SRC_FILES := utils/bcm4751_daemon.c LOCAL_C_INCLUDES += $(LOCAL_PATH)/include @@ -44,7 +44,7 @@ include $(BUILD_EXECUTABLE) include $(CLEAR_VARS) -LOCAL_SRC_FILES := bcm4751_lib.c +LOCAL_SRC_FILES := utils/bcm4751_lib.c LOCAL_C_INCLUDES += $(LOCAL_PATH)/include @@ -55,3 +55,17 @@ LOCAL_MODULE := bcm4751_lib LOCAL_MODULE_TAGS := optional include $(BUILD_EXECUTABLE) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := bcm4751_gpsd.c + +LOCAL_C_INCLUDES += $(LOCAL_PATH) + +LOCAL_SHARED_LIBRARIES := liblog libcutils +LOCAL_PRELINK_MODULE := false + +LOCAL_MODULE := bcm4751_gpsd +LOCAL_MODULE_TAGS := optional + +include $(BUILD_EXECUTABLE) diff --git a/Makefile b/Makefile deleted file mode 100644 index eb48aed..0000000 --- a/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -all: gps-test-crespo - -gps-test-crespo: bcm4751_test.c - $(CC) -o $@ $^ -clean: - rm -f gps-test-crespo diff --git a/bcm4751_daemon.c b/bcm4751_daemon.c deleted file mode 100644 index 3cc3190..0000000 --- a/bcm4751_daemon.c +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (C) 2012 Paul Kocialkowski, contact@paulk.fr, GNU GPLv3+ -// BCM4751 daemon code - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -int main(void) -{ - int fd; - int cfd; - int rc; - - int clen; - char buf[50]; - char status[] = { - 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - struct sockaddr_un caddr; - - fd = socket_local_server("gps", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET); - listen(fd, 1); - printf("socket_local_server passed: %d\n", fd); - - cfd = accept(fd, 0, &clen); - printf("accept passed: %d\n", cfd); - - fd_set fds; - FD_ZERO(&fds); - FD_SET(cfd, &fds); - - while(1) - { - memset(buf, 0, sizeof(buf)); - select(cfd+1, &fds, NULL, NULL, NULL); - rc = read(cfd, buf, 50); - - printf("read %d bytes!\n", rc); - - if(rc == 50) { - write(cfd, status, sizeof(status)); - printf("wrote %d bytes!\n", sizeof(status)); - } - } - - return 0; -} diff --git a/bcm4751_gpsd.c b/bcm4751_gpsd.c new file mode 100644 index 0000000..5072751 --- /dev/null +++ b/bcm4751_gpsd.c @@ -0,0 +1,294 @@ +/** + * This file is part of BCM4751 gpsd + * + * Copyright (C) 2011 Paul Kocialkowski + * + * BCM4751 gpsd is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * BCM4751 gpsd is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BCM4751 gpsd. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "meif.h" + +/* + * Utils + */ + +void hex_dump(void *data, int size) +{ + /* dumps size bytes of *data to stdout. Looks like: + * [0000] 75 6E 6B 6E 6F 77 6E 20 + * 30 FF 00 00 00 00 39 00 unknown 0.....9. + * (in a single line of course) + */ + + unsigned char *p = data; + unsigned char c; + int n; + char bytestr[4] = {0}; + char addrstr[10] = {0}; + char hexstr[ 16*3 + 5] = {0}; + char charstr[16*1 + 5] = {0}; + for(n=1;n<=size;n++) { + if (n%16 == 1) { + /* store address for this line */ + snprintf(addrstr, sizeof(addrstr), "%.4x", + ((unsigned int)p-(unsigned int)data) ); + } + + c = *p; + if (isalnum(c) == 0) { + c = '.'; + } + + /* store hex str (for left side) */ + snprintf(bytestr, sizeof(bytestr), "%02X ", *p); + strncat(hexstr, bytestr, sizeof(hexstr)-strlen(hexstr)-1); + + /* store char str (for right side) */ + snprintf(bytestr, sizeof(bytestr), "%c", c); + strncat(charstr, bytestr, sizeof(charstr)-strlen(charstr)-1); + + if(n%16 == 0) { + /* line completed */ + printf("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr); + hexstr[0] = 0; + charstr[0] = 0; + } else if(n%8 == 0) { + /* half line: add whitespaces */ + strncat(hexstr, " ", sizeof(hexstr)-strlen(hexstr)-1); + strncat(charstr, " ", sizeof(charstr)-strlen(charstr)-1); + } + p++; /* next byte */ + } + + if (strlen(hexstr) > 0) { + /* print rest of buffer if not empty */ + printf("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr); + } +} + +/* + * SEC + */ + +int sec_gps_power(int power) +{ + char gpio_power_path[] = "/sys/class/sec/gps/GPS_PWR_EN/value"; + char gpio_on_value[] = "1\n"; + char gpio_off_value[] = "0\n"; + int fd = -1; + int rc; + + fd = open(gpio_power_path, O_RDWR); + if(fd < 0) + return -1; + + if(power) { + rc = write(fd, gpio_on_value, strlen(gpio_on_value)); + } else { + rc = write(fd, gpio_off_value, strlen(gpio_off_value)); + } + + if(rc <= 0) { + close(fd); + return -1; + } + + close(fd); + + usleep(250000); + + return 0; +} + +int sec_gps_reset(int value) +{ + char gpio_reset_path[] = "/sys/class/sec/gps/GPS_nRST/value"; + char gpio_on_value[] = "1\n"; + char gpio_off_value[] = "0\n"; + int fd = -1; + int rc; + + fd = open(gpio_reset_path, O_RDWR); + if(fd < 0) + return -1; + + if(value) { + rc = write(fd, gpio_on_value, strlen(gpio_on_value)); + } else { + rc = write(fd, gpio_off_value, strlen(gpio_off_value)); + } + + if(rc <= 0) { + close(fd); + return -1; + } + + close(fd); + + usleep(250000); + + return 0; +} + +/* + * BCM4751 + */ + +int bcm4751_serial_open(void) +{ + struct termios termios; + int fd = -1; + + // TODO: add more checks + + fd = open("/dev/s3c2410_serial1", O_RDWR|O_NOCTTY|O_NONBLOCK); + if(fd < 0) + return -1; + + tcgetattr(fd, &termios); + + // Flush + ioctl(fd, TCFLSH, 0x2); + + cfmakeraw(&termios); + cfsetispeed(&termios, B115200); + cfsetospeed(&termios, B115200); + + // This is the magic to contact the chip + termios.c_cflag = 0x800018b2; + + tcsetattr(fd, TCSANOW, &termios); + + // Flush + ioctl(fd, TCFLSH, 0x2); + + return fd; +} + +int bcm4751_serial_read(int fd, void *data, int length, struct timeval *timeout) +{ + fd_set fds; + int rc = -1; + + FD_ZERO(&fds); + FD_SET(fd, &fds); + + rc = select(fd + 1, &fds, NULL, NULL, timeout); + if(rc > 0 && length > 0) { + rc = read(fd, data, length); + } + + return rc; +} + +int bcm4751_serial_write(int fd, void *data, int length, struct timeval *timeout) +{ + fd_set fds; + int rc = -1; + + FD_ZERO(&fds); + FD_SET(fd, &fds); + + rc = select(fd + 1, NULL, &fds, NULL, timeout); + if(rc > 0) { + rc = write(fd, data, length); + } + + return rc; +} + +int bcm4751_autobaud(int fd) +{ + struct timeval timeout; + uint8_t autobaud[20] = { 0x80 }; + int ready = 0; + int rc = -1; + + // TODO: limit the number of attempts + + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + while(!ready) { + bcm4751_serial_write(fd, autobaud, sizeof(autobaud), NULL); + + rc = bcm4751_serial_read(fd, NULL, 0, &timeout); + if(rc > 0) + ready = 1; + } + + return 0; +} + +void bcm4751_read_dump(int fd) +{ + void *data = NULL; + int length = 0x100; + int rc = -1; + + data = malloc(length); + + while(1) { + rc = bcm4751_serial_read(fd, data, length, NULL); + if(rc > 0) { + printf("Read %d bytes:\n", rc); + hex_dump(data, rc); + } else { + free(data); + return; + } + } +} + +int main(void) +{ + int fd = -1; + int rc = -1; + + printf("Turning the GPS on...\n"); + rc = sec_gps_power(1); + if(rc < 0) { + printf("Failed to turn the GPS on!\n"); + return 1; + } + + printf("Opening the GPS serial...\n"); + fd = bcm4751_serial_open(); + if(fd < 0) { + printf("Failed to open the GPS serial!\n"); + return 1; + } + + printf("Sending autobaud...\n"); + rc = bcm4751_autobaud(fd); + if(fd < 0) { + printf("Failed to send autobaud!\n"); + return 1; + } + + bcm4751_read_dump(fd); + + return 0; +} diff --git a/bcm4751_hal.c b/bcm4751_hal.c deleted file mode 100644 index d60bb9e..0000000 --- a/bcm4751_hal.c +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright (C) 2012 Paul Kocialkowski, contact@paulk.fr, GNU GPLv3+ -// BCM4751 HAL code -// This code will open the gps lib only: we can trace it that way - -#include -#include - -#include -#include -#include - -#define WAKE_LOCK_NAME "GPS" - -hw_module_t* module; -hw_device_t* device; - -static const GpsInterface* sGpsInterface = NULL; -static const GpsXtraInterface* sGpsXtraInterface = NULL; -static const AGpsInterface* sAGpsInterface = NULL; -static const GpsNiInterface* sGpsNiInterface = NULL; -static const GpsDebugInterface* sGpsDebugInterface = NULL; -static const AGpsRilInterface* sAGpsRilInterface = NULL; - -static void location_callback(GpsLocation* location) -{ - printf("got a location callback!\n"); -} - -static void status_callback(GpsStatus* status) -{ - printf("got a status callback!\n"); -} - -static void sv_status_callback(GpsSvStatus* sv_status) -{ - printf("got a svstatus callback!\n"); -} - -static void nmea_callback(GpsUtcTime timestamp, const char* nmea, int length) -{ - printf("got a nmea callback: %s!\n", nmea); -} - -static void set_capabilities_callback(uint32_t capabilities) -{ - printf("set_capabilities_callback: %ld\n", capabilities); -} - - -static void acquire_wakelock_callback() -{ - acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); -} - -static void release_wakelock_callback() -{ - release_wake_lock(WAKE_LOCK_NAME); -} - -static pthread_t create_thread_callback(const char* name, void (*start)(void *), void* arg) -{ - printf("doing a thread!\n"); - - pthread_t thread; - pthread_create(&thread, NULL, start, arg); - return thread; -} - -GpsCallbacks sGpsCallbacks = { - sizeof(GpsCallbacks), - location_callback, - status_callback, - sv_status_callback, - nmea_callback, - set_capabilities_callback, - acquire_wakelock_callback, - release_wakelock_callback, - create_thread_callback, -}; - -void hal_init(void) -{ - int rc; - rc = hw_get_module("gps", (hw_module_t const**)&module); - printf("hw_get_module: %d\n", rc); - - if(rc < 0) - return; - - rc = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device); - printf("module->methods->open: %d\n", rc); - - if(rc < 0) - return; - - struct gps_device_t* gps_device = (struct gps_device_t *)device; - sGpsInterface = gps_device->get_gps_interface(gps_device); - - if (sGpsInterface) { - printf("GPS interface ready\n"); - sGpsXtraInterface = - (const GpsXtraInterface*)sGpsInterface->get_extension(GPS_XTRA_INTERFACE); - sAGpsInterface = - (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); - sGpsNiInterface = - (const GpsNiInterface*)sGpsInterface->get_extension(GPS_NI_INTERFACE); - sGpsDebugInterface = - (const GpsDebugInterface*)sGpsInterface->get_extension(GPS_DEBUG_INTERFACE); - sAGpsRilInterface = - (const AGpsRilInterface*)sGpsInterface->get_extension(AGPS_RIL_INTERFACE); - } -} - -void gps_init(void) -{ - int rc; - rc = sGpsInterface->init(&sGpsCallbacks); - printf("sGpsInterface->init: %d\n", rc); - -/* - // if XTRA initialization fails we will disable it by sGpsXtraInterface to null, - // but continue to allow the rest of the GPS interface to work. - if (sGpsXtraInterface && sGpsXtraInterface->init(&sGpsXtraCallbacks) != 0) - sGpsXtraInterface = NULL; - if (sAGpsInterface) - sAGpsInterface->init(&sAGpsCallbacks); - if (sGpsNiInterface) - sGpsNiInterface->init(&sGpsNiCallbacks); - if (sAGpsRilInterface) - sAGpsRilInterface->init(&sAGpsRilCallbacks); -*/ -} - -int main(void) -{ - hal_init(); - gps_init(); - - sleep(1); - - printf("Starting GPS!\n"); - sGpsInterface->start(); - sleep(60); - printf("Stopping GPS!\n"); - sGpsInterface->stop(); - - sleep(60); - - return 0; -} diff --git a/bcm4751_lib.c b/bcm4751_lib.c deleted file mode 100644 index 3dd9e6d..0000000 --- a/bcm4751_lib.c +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) 2012 Paul Kocialkowski, contact@paulk.fr, GNU GPLv3+ -// BCM4751 lib code - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -/* -535 socket(PF_UNIX, SOCK_SEQPACKET, 0) = 3 -535 connect(3, {sa_family=AF_UNIX, path="/dev/socket/gps"}, 110) = 0 - -535 write(3, "\x08\x00\x00\x00\x6b\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00\xff\xff\xff\xff"..., 44) = 44 -535 write(3, "\x08\x00\x00\x00\x6c\x00\x00\x00\x0c\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 24) = 24 -535 write(3, "\x08\x00\x00\x00\x17\x00\x00\x00\x0c\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00", 24) = 24 -535 write(3, "\x08\x00\x00\x00\x08\x00\x00\x00\x30\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00"..., 60) = 60 -*/ -int main(void) -{ - int fd = socket_local_client("gps", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET); - if(fd < 0) { - printf("Socket is dead!\n"); - return 1; - } - - char data1[] = { - 0x08, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x05, 0x93, 0xd2, 0xaf, 0x14, 0xcc, 0xc0, 0xbe - }; - char data2[] = { - 0x08, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - char data3[] = { - 0x08, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - char data4[] = { - 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 - }; -/* - write(fd, data1, sizeof(data1)); - usleep(500000); - write(fd, data2, sizeof(data2)); - usleep(500000); - write(fd, data3, sizeof(data3)); - usleep(500000); -*/ - // Ask GPSD to start obtaining data from the chip - write(fd, data4, sizeof(data4)); - usleep(500000); - - sleep(60); - - return 0; -} diff --git a/bcm4751_test.c b/bcm4751_test.c deleted file mode 100644 index bf4159b..0000000 --- a/bcm4751_test.c +++ /dev/null @@ -1,265 +0,0 @@ -// Copyright (C) 2012 Paul Kocialkowski, contact@paulk.fr, GNU GPLv3+ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -void hex_dump(void *data, int size) -{ - /* dumps size bytes of *data to stdout. Looks like: - * [0000] 75 6E 6B 6E 6F 77 6E 20 - * 30 FF 00 00 00 00 39 00 unknown 0.....9. - * (in a single line of course) - */ - - unsigned char *p = data; - unsigned char c; - int n; - char bytestr[4] = {0}; - char addrstr[10] = {0}; - char hexstr[ 16*3 + 5] = {0}; - char charstr[16*1 + 5] = {0}; - for(n=1;n<=size;n++) { - if (n%16 == 1) { - /* store address for this line */ - snprintf(addrstr, sizeof(addrstr), "%.4x", - ((unsigned int)p-(unsigned int)data) ); - } - - c = *p; - if (isalnum(c) == 0) { - c = '.'; - } - - /* store hex str (for left side) */ - snprintf(bytestr, sizeof(bytestr), "%02X ", *p); - strncat(hexstr, bytestr, sizeof(hexstr)-strlen(hexstr)-1); - - /* store char str (for right side) */ - snprintf(bytestr, sizeof(bytestr), "%c", c); - strncat(charstr, bytestr, sizeof(charstr)-strlen(charstr)-1); - - if(n%16 == 0) { - /* line completed */ - printf("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr); - hexstr[0] = 0; - charstr[0] = 0; - } else if(n%8 == 0) { - /* half line: add whitespaces */ - strncat(hexstr, " ", sizeof(hexstr)-strlen(hexstr)-1); - strncat(charstr, " ", sizeof(charstr)-strlen(charstr)-1); - } - p++; /* next byte */ - } - - if (strlen(hexstr) > 0) { - /* print rest of buffer if not empty */ - printf("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr); - } -} - -int wake_lock_fd = -1; -int wake_unlock_fd = -1; - -int wake_lock(char *lock_name, int size) -{ - int rc = 0; - - if(wake_lock_fd < 0) - wake_lock_fd = open("/sys/power/wake_lock", O_RDWR); - - rc = write(wake_lock_fd, lock_name, size); - - return rc; -} - -int wake_unlock(char *lock_name, int size) -{ - int rc = 0; - - if(wake_lock_fd < 0) - wake_unlock_fd = open("/sys/power/wake_unlock", O_RDWR); - - rc = write(wake_unlock_fd, lock_name, size); - - return rc; -} - -void gpio_write_ascii(char *gpio_path, char *value) -{ - int fd; - fd = open(gpio_path, O_RDWR); - - if(fd < 0) - return; - - write(fd, value, strlen(value)); - - close(fd); -} - -int main(int argc, char *argv[]) -{ - char *gpio_standby_path = "/sys/class/sec/gps/GPS_PWR_EN/value"; - char *gpio_reset_path = "/sys/class/sec/gps/GPS_nRST/value"; - unsigned char *data; - unsigned char init_val[21]; - int serial_fd; - int rc; - int i; - - struct termios termios; - struct timeval timeout; - int serial; - fd_set fds; - - if(argc > 1) { - if(strcmp(argv[1], "stop") == 0) { - printf("Stopping it\n"); - wake_unlock("gpsd-interface", 14); - gpio_write_ascii(gpio_standby_path, "0\n"); - - return 0; - } - } - - sleep(1); - - printf("Wake lock on gpsd-interface\n"); - - wake_lock("gpsd-interface", 14); - - printf("GPIO 1 write on %s\n", gpio_standby_path); - gpio_write_ascii(gpio_standby_path, "1\n"); - - usleep(250000); - - printf("Opening /dev/s3c2410_serial1\n"); - serial_fd = open("/dev/s3c2410_serial1", O_RDWR|O_NOCTTY|O_NONBLOCK); - - if(serial_fd < 0) { - printf("Serial fd is wrong, aborting\n"); - return 1; - } - - tcgetattr(serial_fd, &termios); - ioctl(serial_fd, TCFLSH, 0x2); - - cfmakeraw(&termios); - cfsetispeed(&termios, B115200); - cfsetospeed(&termios, B115200); - - // This is the magic to contact the chip - termios.c_cflag = 0x800018b2; -// termios.c_cc[5]=0x01; -// termios.c_cc[6]=0x00; - - tcsetattr(serial_fd, TCSANOW, &termios); - ioctl(serial_fd, TCFLSH, 0x2); - tcgetattr(serial_fd, &termios); - - FD_ZERO(&fds); - FD_SET(serial_fd, &fds); - - memset(init_val, 0x80, 21); - data = malloc(512); - - timeout.tv_sec = 1; - timeout.tv_usec = 0; - - printf("Writing init bits\n"); - - rc = select(serial_fd + 1, NULL, &fds, NULL, &timeout); - if(rc > 0) { - write(serial_fd, init_val, 20); - printf("Written\n"); - } else { - printf("Timeout!\n"); - return 0; - } - - for(i=0 ; i < 3 ; i++) { - timeout.tv_sec = 1; - timeout.tv_usec = 0; - - rc = select(serial_fd + 1, &fds, NULL, NULL, &timeout); - - printf("select rc is %d\n", rc); - - if(rc > 0) { - rc = read(serial_fd, data, 512); - printf("read %d bytes!\n", rc); - - if(rc < 0) { - wake_unlock("gpsd-interface", 14); - gpio_write_ascii(gpio_standby_path, "0\n"); - return 0; - } - - hex_dump(data, rc); - break; - } - - write(serial_fd, init_val, 20); - } - - for(i=0 ; i < 3 ; i++) { - rc = read(serial_fd, data, 512); - printf("read %d bytes!\n", rc); - - if(rc < 0) { - perror("Here comes the error"); - } else - hex_dump(data, rc); - - usleep(250000); - } - - wake_unlock("gpsd-interface", 14); - gpio_write_ascii(gpio_standby_path, "0\n"); - - return 0; - - printf("Writing MEIF init bits\n"); - - unsigned char meif_init_bits[9] = { - 0xff, 0x00, 0xfd, 0x40, 0x00, 0x00, 0xe6, 0xfc - }; - - write(serial_fd, meif_init_bits, 8); - - - while(1) { - FD_ZERO(&fds); - FD_SET(serial_fd, &fds); - - timeout.tv_sec = 1; - timeout.tv_usec = 499000; - - rc = select(serial_fd + 1, &fds, NULL, NULL, &timeout); - - printf("select rc is %d\n", rc); - - if(rc > 0) { - rc = read(serial_fd, data, 512); - printf("read %d bytes!\n"); - hex_dump(data, rc); - - // usleep(30000); - } - } - - free(data); - - return 0; -} diff --git a/meif.h b/meif.h new file mode 100644 index 0000000..f79b9b8 --- /dev/null +++ b/meif.h @@ -0,0 +1,67 @@ +/** + * This file is part of BCM4751 gpsd + * + * Copyright (C) 2011 Paul Kocialkowski + * + * BCM4751 gpsd is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * BCM4751 gpsd is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BCM4751 gpsd. If not, see . + */ + +#include +#include +#include + +#ifndef _MEIF_H_ +#define _MEIF_H_ + +#define MEIF_START 0xA593 +#define MEIF_END 0xA568 + +/* + * Commands + */ + +#define MEIF_ACK_MSG 0x0000 +#define MEIF_NACK_MSG 0x0001 +//#define MEIF_ERROR_MSG 0x0002 or 0x0003 +#define MEIF_STATE_REPORT_MSG 0x0004 +#define MEIF_CONFIG_VALUES_MSG 0x0008 + +/* + * Data + */ + +/* + * Structures + */ + +struct meif_message { + uint16_t command; + uint16_t length; + void *data; +} __attribute__((__packed__)); + +struct meif_config_values_report { + uint8_t unknown1[36]; + char vendor[16]; + char product[16]; + uint8_t unknown2[2]; +} __attribute__((__packed__)); + +/* + * Functions + */ + +void meif_read_loop(int fd); + +#endif diff --git a/utils/Makefile b/utils/Makefile new file mode 100644 index 0000000..eb48aed --- /dev/null +++ b/utils/Makefile @@ -0,0 +1,6 @@ +all: gps-test-crespo + +gps-test-crespo: bcm4751_test.c + $(CC) -o $@ $^ +clean: + rm -f gps-test-crespo diff --git a/utils/bcm4751_daemon.c b/utils/bcm4751_daemon.c new file mode 100644 index 0000000..3cc3190 --- /dev/null +++ b/utils/bcm4751_daemon.c @@ -0,0 +1,60 @@ +// Copyright (C) 2012 Paul Kocialkowski, contact@paulk.fr, GNU GPLv3+ +// BCM4751 daemon code + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +int main(void) +{ + int fd; + int cfd; + int rc; + + int clen; + char buf[50]; + char status[] = { + 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + struct sockaddr_un caddr; + + fd = socket_local_server("gps", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET); + listen(fd, 1); + printf("socket_local_server passed: %d\n", fd); + + cfd = accept(fd, 0, &clen); + printf("accept passed: %d\n", cfd); + + fd_set fds; + FD_ZERO(&fds); + FD_SET(cfd, &fds); + + while(1) + { + memset(buf, 0, sizeof(buf)); + select(cfd+1, &fds, NULL, NULL, NULL); + rc = read(cfd, buf, 50); + + printf("read %d bytes!\n", rc); + + if(rc == 50) { + write(cfd, status, sizeof(status)); + printf("wrote %d bytes!\n", sizeof(status)); + } + } + + return 0; +} diff --git a/utils/bcm4751_hal.c b/utils/bcm4751_hal.c new file mode 100644 index 0000000..d60bb9e --- /dev/null +++ b/utils/bcm4751_hal.c @@ -0,0 +1,150 @@ +// Copyright (C) 2012 Paul Kocialkowski, contact@paulk.fr, GNU GPLv3+ +// BCM4751 HAL code +// This code will open the gps lib only: we can trace it that way + +#include +#include + +#include +#include +#include + +#define WAKE_LOCK_NAME "GPS" + +hw_module_t* module; +hw_device_t* device; + +static const GpsInterface* sGpsInterface = NULL; +static const GpsXtraInterface* sGpsXtraInterface = NULL; +static const AGpsInterface* sAGpsInterface = NULL; +static const GpsNiInterface* sGpsNiInterface = NULL; +static const GpsDebugInterface* sGpsDebugInterface = NULL; +static const AGpsRilInterface* sAGpsRilInterface = NULL; + +static void location_callback(GpsLocation* location) +{ + printf("got a location callback!\n"); +} + +static void status_callback(GpsStatus* status) +{ + printf("got a status callback!\n"); +} + +static void sv_status_callback(GpsSvStatus* sv_status) +{ + printf("got a svstatus callback!\n"); +} + +static void nmea_callback(GpsUtcTime timestamp, const char* nmea, int length) +{ + printf("got a nmea callback: %s!\n", nmea); +} + +static void set_capabilities_callback(uint32_t capabilities) +{ + printf("set_capabilities_callback: %ld\n", capabilities); +} + + +static void acquire_wakelock_callback() +{ + acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); +} + +static void release_wakelock_callback() +{ + release_wake_lock(WAKE_LOCK_NAME); +} + +static pthread_t create_thread_callback(const char* name, void (*start)(void *), void* arg) +{ + printf("doing a thread!\n"); + + pthread_t thread; + pthread_create(&thread, NULL, start, arg); + return thread; +} + +GpsCallbacks sGpsCallbacks = { + sizeof(GpsCallbacks), + location_callback, + status_callback, + sv_status_callback, + nmea_callback, + set_capabilities_callback, + acquire_wakelock_callback, + release_wakelock_callback, + create_thread_callback, +}; + +void hal_init(void) +{ + int rc; + rc = hw_get_module("gps", (hw_module_t const**)&module); + printf("hw_get_module: %d\n", rc); + + if(rc < 0) + return; + + rc = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device); + printf("module->methods->open: %d\n", rc); + + if(rc < 0) + return; + + struct gps_device_t* gps_device = (struct gps_device_t *)device; + sGpsInterface = gps_device->get_gps_interface(gps_device); + + if (sGpsInterface) { + printf("GPS interface ready\n"); + sGpsXtraInterface = + (const GpsXtraInterface*)sGpsInterface->get_extension(GPS_XTRA_INTERFACE); + sAGpsInterface = + (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); + sGpsNiInterface = + (const GpsNiInterface*)sGpsInterface->get_extension(GPS_NI_INTERFACE); + sGpsDebugInterface = + (const GpsDebugInterface*)sGpsInterface->get_extension(GPS_DEBUG_INTERFACE); + sAGpsRilInterface = + (const AGpsRilInterface*)sGpsInterface->get_extension(AGPS_RIL_INTERFACE); + } +} + +void gps_init(void) +{ + int rc; + rc = sGpsInterface->init(&sGpsCallbacks); + printf("sGpsInterface->init: %d\n", rc); + +/* + // if XTRA initialization fails we will disable it by sGpsXtraInterface to null, + // but continue to allow the rest of the GPS interface to work. + if (sGpsXtraInterface && sGpsXtraInterface->init(&sGpsXtraCallbacks) != 0) + sGpsXtraInterface = NULL; + if (sAGpsInterface) + sAGpsInterface->init(&sAGpsCallbacks); + if (sGpsNiInterface) + sGpsNiInterface->init(&sGpsNiCallbacks); + if (sAGpsRilInterface) + sAGpsRilInterface->init(&sAGpsRilCallbacks); +*/ +} + +int main(void) +{ + hal_init(); + gps_init(); + + sleep(1); + + printf("Starting GPS!\n"); + sGpsInterface->start(); + sleep(60); + printf("Stopping GPS!\n"); + sGpsInterface->stop(); + + sleep(60); + + return 0; +} diff --git a/utils/bcm4751_lib.c b/utils/bcm4751_lib.c new file mode 100644 index 0000000..3dd9e6d --- /dev/null +++ b/utils/bcm4751_lib.c @@ -0,0 +1,65 @@ +// Copyright (C) 2012 Paul Kocialkowski, contact@paulk.fr, GNU GPLv3+ +// BCM4751 lib code + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +/* +535 socket(PF_UNIX, SOCK_SEQPACKET, 0) = 3 +535 connect(3, {sa_family=AF_UNIX, path="/dev/socket/gps"}, 110) = 0 + +535 write(3, "\x08\x00\x00\x00\x6b\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00\xff\xff\xff\xff"..., 44) = 44 +535 write(3, "\x08\x00\x00\x00\x6c\x00\x00\x00\x0c\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 24) = 24 +535 write(3, "\x08\x00\x00\x00\x17\x00\x00\x00\x0c\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00", 24) = 24 +535 write(3, "\x08\x00\x00\x00\x08\x00\x00\x00\x30\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00"..., 60) = 60 +*/ +int main(void) +{ + int fd = socket_local_client("gps", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET); + if(fd < 0) { + printf("Socket is dead!\n"); + return 1; + } + + char data1[] = { + 0x08, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x05, 0x93, 0xd2, 0xaf, 0x14, 0xcc, 0xc0, 0xbe + }; + char data2[] = { + 0x08, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + char data3[] = { + 0x08, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + char data4[] = { + 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 + }; +/* + write(fd, data1, sizeof(data1)); + usleep(500000); + write(fd, data2, sizeof(data2)); + usleep(500000); + write(fd, data3, sizeof(data3)); + usleep(500000); +*/ + // Ask GPSD to start obtaining data from the chip + write(fd, data4, sizeof(data4)); + usleep(500000); + + sleep(60); + + return 0; +} diff --git a/utils/bcm4751_test.c b/utils/bcm4751_test.c new file mode 100644 index 0000000..bf4159b --- /dev/null +++ b/utils/bcm4751_test.c @@ -0,0 +1,265 @@ +// Copyright (C) 2012 Paul Kocialkowski, contact@paulk.fr, GNU GPLv3+ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +void hex_dump(void *data, int size) +{ + /* dumps size bytes of *data to stdout. Looks like: + * [0000] 75 6E 6B 6E 6F 77 6E 20 + * 30 FF 00 00 00 00 39 00 unknown 0.....9. + * (in a single line of course) + */ + + unsigned char *p = data; + unsigned char c; + int n; + char bytestr[4] = {0}; + char addrstr[10] = {0}; + char hexstr[ 16*3 + 5] = {0}; + char charstr[16*1 + 5] = {0}; + for(n=1;n<=size;n++) { + if (n%16 == 1) { + /* store address for this line */ + snprintf(addrstr, sizeof(addrstr), "%.4x", + ((unsigned int)p-(unsigned int)data) ); + } + + c = *p; + if (isalnum(c) == 0) { + c = '.'; + } + + /* store hex str (for left side) */ + snprintf(bytestr, sizeof(bytestr), "%02X ", *p); + strncat(hexstr, bytestr, sizeof(hexstr)-strlen(hexstr)-1); + + /* store char str (for right side) */ + snprintf(bytestr, sizeof(bytestr), "%c", c); + strncat(charstr, bytestr, sizeof(charstr)-strlen(charstr)-1); + + if(n%16 == 0) { + /* line completed */ + printf("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr); + hexstr[0] = 0; + charstr[0] = 0; + } else if(n%8 == 0) { + /* half line: add whitespaces */ + strncat(hexstr, " ", sizeof(hexstr)-strlen(hexstr)-1); + strncat(charstr, " ", sizeof(charstr)-strlen(charstr)-1); + } + p++; /* next byte */ + } + + if (strlen(hexstr) > 0) { + /* print rest of buffer if not empty */ + printf("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr); + } +} + +int wake_lock_fd = -1; +int wake_unlock_fd = -1; + +int wake_lock(char *lock_name, int size) +{ + int rc = 0; + + if(wake_lock_fd < 0) + wake_lock_fd = open("/sys/power/wake_lock", O_RDWR); + + rc = write(wake_lock_fd, lock_name, size); + + return rc; +} + +int wake_unlock(char *lock_name, int size) +{ + int rc = 0; + + if(wake_lock_fd < 0) + wake_unlock_fd = open("/sys/power/wake_unlock", O_RDWR); + + rc = write(wake_unlock_fd, lock_name, size); + + return rc; +} + +void gpio_write_ascii(char *gpio_path, char *value) +{ + int fd; + fd = open(gpio_path, O_RDWR); + + if(fd < 0) + return; + + write(fd, value, strlen(value)); + + close(fd); +} + +int main(int argc, char *argv[]) +{ + char *gpio_standby_path = "/sys/class/sec/gps/GPS_PWR_EN/value"; + char *gpio_reset_path = "/sys/class/sec/gps/GPS_nRST/value"; + unsigned char *data; + unsigned char init_val[21]; + int serial_fd; + int rc; + int i; + + struct termios termios; + struct timeval timeout; + int serial; + fd_set fds; + + if(argc > 1) { + if(strcmp(argv[1], "stop") == 0) { + printf("Stopping it\n"); + wake_unlock("gpsd-interface", 14); + gpio_write_ascii(gpio_standby_path, "0\n"); + + return 0; + } + } + + sleep(1); + + printf("Wake lock on gpsd-interface\n"); + + wake_lock("gpsd-interface", 14); + + printf("GPIO 1 write on %s\n", gpio_standby_path); + gpio_write_ascii(gpio_standby_path, "1\n"); + + usleep(250000); + + printf("Opening /dev/s3c2410_serial1\n"); + serial_fd = open("/dev/s3c2410_serial1", O_RDWR|O_NOCTTY|O_NONBLOCK); + + if(serial_fd < 0) { + printf("Serial fd is wrong, aborting\n"); + return 1; + } + + tcgetattr(serial_fd, &termios); + ioctl(serial_fd, TCFLSH, 0x2); + + cfmakeraw(&termios); + cfsetispeed(&termios, B115200); + cfsetospeed(&termios, B115200); + + // This is the magic to contact the chip + termios.c_cflag = 0x800018b2; +// termios.c_cc[5]=0x01; +// termios.c_cc[6]=0x00; + + tcsetattr(serial_fd, TCSANOW, &termios); + ioctl(serial_fd, TCFLSH, 0x2); + tcgetattr(serial_fd, &termios); + + FD_ZERO(&fds); + FD_SET(serial_fd, &fds); + + memset(init_val, 0x80, 21); + data = malloc(512); + + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + printf("Writing init bits\n"); + + rc = select(serial_fd + 1, NULL, &fds, NULL, &timeout); + if(rc > 0) { + write(serial_fd, init_val, 20); + printf("Written\n"); + } else { + printf("Timeout!\n"); + return 0; + } + + for(i=0 ; i < 3 ; i++) { + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + rc = select(serial_fd + 1, &fds, NULL, NULL, &timeout); + + printf("select rc is %d\n", rc); + + if(rc > 0) { + rc = read(serial_fd, data, 512); + printf("read %d bytes!\n", rc); + + if(rc < 0) { + wake_unlock("gpsd-interface", 14); + gpio_write_ascii(gpio_standby_path, "0\n"); + return 0; + } + + hex_dump(data, rc); + break; + } + + write(serial_fd, init_val, 20); + } + + for(i=0 ; i < 3 ; i++) { + rc = read(serial_fd, data, 512); + printf("read %d bytes!\n", rc); + + if(rc < 0) { + perror("Here comes the error"); + } else + hex_dump(data, rc); + + usleep(250000); + } + + wake_unlock("gpsd-interface", 14); + gpio_write_ascii(gpio_standby_path, "0\n"); + + return 0; + + printf("Writing MEIF init bits\n"); + + unsigned char meif_init_bits[9] = { + 0xff, 0x00, 0xfd, 0x40, 0x00, 0x00, 0xe6, 0xfc + }; + + write(serial_fd, meif_init_bits, 8); + + + while(1) { + FD_ZERO(&fds); + FD_SET(serial_fd, &fds); + + timeout.tv_sec = 1; + timeout.tv_usec = 499000; + + rc = select(serial_fd + 1, &fds, NULL, NULL, &timeout); + + printf("select rc is %d\n", rc); + + if(rc > 0) { + rc = read(serial_fd, data, 512); + printf("read %d bytes!\n"); + hex_dump(data, rc); + + // usleep(30000); + } + } + + free(data); + + return 0; +} -- cgit v1.2.3