From e696ed2427fe036a0dcfe50f209e22a9f273d100 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 20 Aug 2016 20:55:43 +0100 Subject: working calls --- app/Makefile | 3 +- app/buzzer.c | 143 ++++++++++++++++ app/cdc.c | 154 ----------------- app/cdcacm.c | 155 ++++++++++++++++++ app/console.c | 17 ++ app/gpio.c | 86 ++++++++++ app/led.c | 2 + app/main.c | 27 ++- app/modem.c | 99 +++++++++++ app/project.h | 6 +- app/prototypes.h | 50 +++++- app/ring.c | 68 ++++++++ app/ring.h | 7 + app/serial.c | 30 ++++ app/ticker.c | 5 +- app/usart.c | 227 ++++++++++++++++++++++++++ app/usb.c | 1 + doc/SIM800 Series_AT Command Manual_V1.09.pdf | Bin 0 -> 3221609 bytes 18 files changed, 920 insertions(+), 160 deletions(-) create mode 100644 app/buzzer.c delete mode 100644 app/cdc.c create mode 100644 app/cdcacm.c create mode 100644 app/console.c create mode 100644 app/gpio.c create mode 100644 app/modem.c create mode 100644 app/ring.c create mode 100644 app/ring.h create mode 100644 app/serial.c create mode 100644 app/usart.c create mode 100644 doc/SIM800 Series_AT Command Manual_V1.09.pdf diff --git a/app/Makefile b/app/Makefile index afb5bc1..657109f 100644 --- a/app/Makefile +++ b/app/Makefile @@ -25,7 +25,8 @@ PROG=candlestick V=1 default: ${PROG}.elf -CSRCS=dfu.c main.c usb.c led.c ticker.c i2c.c lcd.c cdc.c +CSRCS=dfu.c main.c usb.c led.c ticker.c i2c.c lcd.c cdcacm.c usart.c ring.c serial.c gpio.c console.c buzzer.c modem.c + BINARY = ${PROG} diff --git a/app/buzzer.c b/app/buzzer.c new file mode 100644 index 0000000..4c45630 --- /dev/null +++ b/app/buzzer.c @@ -0,0 +1,143 @@ +#include "project.h" + +static int period; +static int place; +int ringing; + + +#define C6 1047 +#define E6 1319 + +void buzzer_on(void) +{ + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, + GPIO_TIM1_CH1); + gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, + GPIO_TIM1_CH1N); + + timer_reset(TIM1); + + timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_CENTER_1, TIM_CR1_DIR_UP); + timer_set_oc_mode(TIM1, TIM_OC1, TIM_OCM_PWM2); + timer_enable_oc_output(TIM1, TIM_OC1); + timer_enable_oc_output(TIM1, TIM_OC1N); + timer_enable_break_main_output(TIM1); + + timer_set_oc_value(TIM1, TIM_OC1, period/2); + timer_set_period(TIM1, period); + + timer_enable_counter(TIM1); +} +void buzzer_off(void) +{ + gpio_set_mode (GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO8); + gpio_clear(GPIOA,GPIO8); + gpio_set_mode (GPIOB, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO13); + gpio_clear(GPIOB,GPIO13); + timer_disable_counter(TIM1); +} + +void buzzer_set_freq(int hz) +{ + period=(48000000/4)/hz; + timer_set_oc_value(TIM1, TIM_OC1, period/2); + timer_set_period(TIM1, period); +} + +void buzzer_init(void) +{ + + /*buzzer*/ + buzzer_off(); + buzzer_set_freq(440); + +} + + +void ring_tick(void) +{ +static int t; + +if (!ringing) return; +ringing--; + +if (!ringing) { + place=0; + buzzer_off(); + return; +} + + + +t++; +if (t<50) return; +t=0; + + +switch(place){ +case 1: +case 3: +case 5: +case 7: + +case 13: +case 15: +case 17: +case 19: + place++; + buzzer_set_freq(C6); + break; + +case 0: +case 12: + place++; + buzzer_set_freq(E6); + buzzer_on(); + break; +case 2: +case 4: +case 6: +case 14: +case 16: +case 18: + place++; + buzzer_set_freq(E6); + break; + +case 8: +case 20: + place++; + buzzer_off(); + break; + +default: + place++; + break; +case 59: + place=0; +} + + + + +} + + +void ring_off(void) +{ +place=0; +ringing=0; +buzzer_off(); +} + +void ring(int l) +{ +//mb(); +ringing=l; +} + + + + diff --git a/app/cdc.c b/app/cdc.c deleted file mode 100644 index 4088b6c..0000000 --- a/app/cdc.c +++ /dev/null @@ -1,154 +0,0 @@ -#include "project.h" - -static const struct usb_endpoint_descriptor comm_endp[] = { - { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x83, - .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, - .wMaxPacketSize = 16, - .bInterval = 255, - } -}; - -static const struct usb_endpoint_descriptor data_endp[] = { - { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x01, - .bmAttributes = USB_ENDPOINT_ATTR_BULK, - .wMaxPacketSize = 64, - .bInterval = 1, - }, - { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x82, - .bmAttributes = USB_ENDPOINT_ATTR_BULK, - .wMaxPacketSize = 64, - .bInterval = 1, - } -}; - -static const struct { - struct usb_cdc_header_descriptor header; - struct usb_cdc_call_management_descriptor call_mgmt; - struct usb_cdc_acm_descriptor acm; - struct usb_cdc_union_descriptor cdc_union; -} __attribute__((packed)) cdcacm_functional_descriptors = { - .header = { - .bFunctionLength = sizeof(struct usb_cdc_header_descriptor), - .bDescriptorType = CS_INTERFACE, - .bDescriptorSubtype = USB_CDC_TYPE_HEADER, - .bcdCDC = 0x0110, - }, - .call_mgmt = { - .bFunctionLength = - sizeof(struct usb_cdc_call_management_descriptor), - .bDescriptorType = CS_INTERFACE, - .bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT, - .bmCapabilities = 0, - .bDataInterface = 1, - }, - .acm = { - .bFunctionLength = sizeof(struct usb_cdc_acm_descriptor), - .bDescriptorType = CS_INTERFACE, - .bDescriptorSubtype = USB_CDC_TYPE_ACM, - .bmCapabilities = 0, - }, - .cdc_union = { - .bFunctionLength = sizeof(struct usb_cdc_union_descriptor), - .bDescriptorType = CS_INTERFACE, - .bDescriptorSubtype = USB_CDC_TYPE_UNION, - .bControlInterface = 0, - .bSubordinateInterface0 = 1, - } -}; - -const struct usb_interface_descriptor comm_iface[] = { - { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bAlternateSetting = 0, - .bNumEndpoints = 1, - .bInterfaceClass = USB_CLASS_CDC, - .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, - .bInterfaceProtocol = USB_CDC_PROTOCOL_AT, - .iInterface = 0, - .endpoint = comm_endp, - .extra = &cdcacm_functional_descriptors, - .extralen = sizeof(cdcacm_functional_descriptors) - } -}; - -const struct usb_interface_descriptor data_iface[] = { - { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 1, - .bAlternateSetting = 0, - .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_DATA, - .bInterfaceSubClass = 0, - .bInterfaceProtocol = 0, - .iInterface = 0, - .endpoint = data_endp, - } -}; - - -int cdcacm_control_request(usbd_device *usbd_dev, - struct usb_setup_data *req, - uint8_t **buf, - uint16_t *len, - int (**complete)(usbd_device *usbd_dev, - struct usb_setup_data *req)) -{ - (void)complete; - (void)buf; - (void)usbd_dev; - - switch(req->bRequest) { - case USB_CDC_REQ_SET_CONTROL_LINE_STATE: { - /* - * This Linux cdc_acm driver requires this to be implemented - * even though it's optional in the CDC spec, and we don't - * advertise it in the ACM functional descriptor. - */ - char local_buf[10]; - struct usb_cdc_notification *notif = (void *)local_buf; - - /* We echo signals back to host as notification. */ - notif->bmRequestType = 0xA1; - notif->bNotification = USB_CDC_NOTIFY_SERIAL_STATE; - notif->wValue = 0; - notif->wIndex = 0; - notif->wLength = 2; - local_buf[8] = req->wValue & 3; - local_buf[9] = 0; - // usbd_ep_write_packet(0x83, buf, 10); - return 1; - } - case USB_CDC_REQ_SET_LINE_CODING: - if(*len < sizeof(struct usb_cdc_line_coding)) { - return 0; - } - return 1; - } - return 0; -} - -void cdcacm_data_rx_cb(usbd_device *usbd_dev, uint8_t ep) -{ - (void)ep; - char buf[64]; - int len = usbd_ep_read_packet(usbd_dev, 0x01, buf, 64); - - - if (len) { - buf[0]^=32; - usbd_ep_write_packet(usbd_dev, 0x82, buf, len); - buf[len] = 0; - } -} diff --git a/app/cdcacm.c b/app/cdcacm.c new file mode 100644 index 0000000..930d5ec --- /dev/null +++ b/app/cdcacm.c @@ -0,0 +1,155 @@ +#include "project.h" + +static const struct usb_endpoint_descriptor comm_endp[] = { + { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x83, + .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, + .wMaxPacketSize = 16, + .bInterval = 255, + } +}; + +static const struct usb_endpoint_descriptor data_endp[] = { + { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x01, + .bmAttributes = USB_ENDPOINT_ATTR_BULK, + .wMaxPacketSize = 64, + .bInterval = 1, + }, + { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x82, + .bmAttributes = USB_ENDPOINT_ATTR_BULK, + .wMaxPacketSize = 64, + .bInterval = 1, + } +}; + +static const struct { + struct usb_cdc_header_descriptor header; + struct usb_cdc_call_management_descriptor call_mgmt; + struct usb_cdc_acm_descriptor acm; + struct usb_cdc_union_descriptor cdc_union; +} __attribute__((packed)) cdcacm_functional_descriptors = { + .header = { + .bFunctionLength = sizeof(struct usb_cdc_header_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_CDC_TYPE_HEADER, + .bcdCDC = 0x0110, + }, + .call_mgmt = { + .bFunctionLength = + sizeof(struct usb_cdc_call_management_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT, + .bmCapabilities = 0, + .bDataInterface = 1, + }, + .acm = { + .bFunctionLength = sizeof(struct usb_cdc_acm_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_CDC_TYPE_ACM, + .bmCapabilities = 0, + }, + .cdc_union = { + .bFunctionLength = sizeof(struct usb_cdc_union_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_CDC_TYPE_UNION, + .bControlInterface = 0, + .bSubordinateInterface0 = 1, + } +}; + +const struct usb_interface_descriptor comm_iface[] = { + { + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = USB_CLASS_CDC, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, + .bInterfaceProtocol = USB_CDC_PROTOCOL_AT, + .iInterface = 0, + .endpoint = comm_endp, + .extra = &cdcacm_functional_descriptors, + .extralen = sizeof(cdcacm_functional_descriptors) + } +}; + +const struct usb_interface_descriptor data_iface[] = { + { + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 1, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_DATA, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = 0, + .iInterface = 0, + .endpoint = data_endp, + } +}; + + +int cdcacm_control_request(usbd_device *usbd_dev, + struct usb_setup_data *req, + uint8_t **buf, + uint16_t *len, + int (**complete)(usbd_device *usbd_dev, + struct usb_setup_data *req)) +{ + (void)complete; + (void)buf; + (void)usbd_dev; + + switch(req->bRequest) { + case USB_CDC_REQ_SET_CONTROL_LINE_STATE: { + /* + * This Linux cdc_acm driver requires this to be implemented + * even though it's optional in the CDC spec, and we don't + * advertise it in the ACM functional descriptor. + */ + char local_buf[10]; + struct usb_cdc_notification *notif = (void *)local_buf; + + /* We echo signals back to host as notification. */ + notif->bmRequestType = 0xA1; + notif->bNotification = USB_CDC_NOTIFY_SERIAL_STATE; + notif->wValue = 0; + notif->wIndex = 0; + notif->wLength = 2; + local_buf[8] = req->wValue & 3; + local_buf[9] = 0; + // usbd_ep_write_packet(0x83, buf, 10); + return 1; + } + case USB_CDC_REQ_SET_LINE_CODING: + if(*len < sizeof(struct usb_cdc_line_coding)) { + return 0; + } + return 1; + } + return 0; +} + +void cdcacm_data_tx(void *buf,size_t len) +{ + usbd_ep_write_packet(usbd_dev, 0x82, buf, len); +} + +void cdcacm_data_rx_cb(usbd_device *usbd_dev, uint8_t ep) +{ + (void)ep; + char buf[64]; + int len = usbd_ep_read_packet(usbd_dev, 0x01, buf, 64); + + if (len) + usart2_tx(buf,len); +} diff --git a/app/console.c b/app/console.c new file mode 100644 index 0000000..ae32e38 --- /dev/null +++ b/app/console.c @@ -0,0 +1,17 @@ +#include "project.h" + + + + + + + +int console_tx(void *buf,size_t len) +{ + + +usart1_tx(buf,len); + + +return len; +} diff --git a/app/gpio.c b/app/gpio.c new file mode 100644 index 0000000..2eb41ce --- /dev/null +++ b/app/gpio.c @@ -0,0 +1,86 @@ +#include "project.h" + +static int hs_poll=50,hook=-1; + +static int fake_hook; + +void exti15_10_isr(void) +{ + exti_reset_request(EXTI14); +hs_poll=50; +} + +static void hs_tick(void) +{ +int h; +if (!hs_poll) return; +hs_poll--; + +if (hs_poll) return; + +h=!!gpio_get(GPIOC,GPIO14); + +h^=fake_hook; + +if (hook==h) return; + +hook=h; + +printf("Hook is now %d\r\n",hook); + +if ((!hook) && (ringing)) { + ring_off(); + answer_call(); + +} + +if (hook) { + ring_off(); + terminate_call(); +} + + + + + +} + + +void toggle_fake_hook(void) +{ +fake_hook^=1; +hs_poll=50; +} + +void gpio_tick(void) +{ +hs_tick(); +} + + + + + +void gpio_init(void) +{ + /*GSM module reset pin*/ + gpio_set_mode (GPIOA, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO1); + gpio_set(GPIOA,GPIO1); + + + /*hookswitch*/ + gpio_set_mode (GPIOC, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO15); + gpio_set(GPIOC,GPIO15); + + gpio_set_mode (GPIOC, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO14); + gpio_clear(GPIOC,GPIO14); + + + exti_select_source(EXTI14, GPIOC); + exti_set_trigger(EXTI14, EXTI_TRIGGER_BOTH); + exti_enable_request(EXTI14); + + nvic_enable_irq(NVIC_EXTI15_10_IRQ); + +} diff --git a/app/led.c b/app/led.c index bda76ea..a6a688b 100644 --- a/app/led.c +++ b/app/led.c @@ -43,5 +43,7 @@ led_tick (void) else gpio_set (GPIOC, GPIO13); + + } diff --git a/app/main.c b/app/main.c index 4c56b55..00dbc85 100644 --- a/app/main.c +++ b/app/main.c @@ -19,19 +19,42 @@ main (void) rcc_periph_clock_enable (RCC_GPIOB); rcc_periph_clock_enable (RCC_GPIOC); rcc_periph_clock_enable (RCC_AFIO); +rcc_periph_clock_enable(RCC_TIM1); + + nvic_set_priority (NVIC_USART1_IRQ, 0x40); + nvic_set_priority (NVIC_USART2_IRQ, 0x40); + nvic_set_priority (NVIC_SYSTICK_IRQ, 0xff); ticker_init (); led_init (); + usart_init(); + + gpio_init(); + buzzer_init(); + + modem_init(); + + #if 0 i2c_bb_init (); lcd_init (); #endif - usb_init (); - usb_run (); + //usb_init (); + + /*Reset the GSM module*/ + gpio_clear(GPIOA,GPIO1); + delay_ms(100); + gpio_set(GPIOA,GPIO1); + + + //usb_run (); + for (;;) { + serial_poll(); + } return 0; } diff --git a/app/modem.c b/app/modem.c new file mode 100644 index 0000000..fa6a57a --- /dev/null +++ b/app/modem.c @@ -0,0 +1,99 @@ +#include "project.h" + +#define BUFFER_SIZE 32 + +#define TIMEOUT 500 +#define SLEEPY 550 +#define BACKOFF 200 + +static char modem_buf[BUFFER_SIZE]; +static unsigned modem_ptr=0; +static char *modem_cmd; +static int timeout; +static int sleepy=SLEEPY; + + + + +void modem_send(char *buf) +{ +modem_cmd=buf; + +if (sleepy>=SLEEPY) { + printf("modem is sleepy\r\n"); + usart2_queue('\r'); + sleepy=0; + timeout=BACKOFF; + return; +} + sleepy=0; + +printf("(re)send\r\n"); +timeout=TIMEOUT; +usart2_queue('\r'); +usart2_tx(modem_cmd,strlen(modem_cmd)); +usart2_queue('\r'); +} + + +void modem_line() +{ +printf("Modem said: %s\r\n",modem_buf); + +sleepy=0; + +if (!strncmp(modem_buf,"RING",4)) + ring(4000); + +if (!strncmp(modem_buf,"OK",2)) { + modem_cmd=NULL; + timeout=0; +} +} + +void modem_byte(uint8_t b) +{ + +if (b=='\n') return; + +if (b=='\r') { + if (modem_ptr) + modem_line(); + modem_ptr=0; + modem_buf[modem_ptr]=0; + return; +} + +if (modem_ptr>=(sizeof(modem_buf)-1)) + return; + +modem_buf[modem_ptr]=b; +modem_ptr++; +modem_buf[modem_ptr]=0; +} + +void answer_call(void) +{ + printf("Answering call\r\n"); + modem_send("ATA"); +} + +void terminate_call(void) { + printf("Terminating any call\r\n"); + modem_send("ATH0"); +} + +void modem_tick(void) { + +if (sleepy #include #include +#include +#include #include #include +#include #include #include -#include #include #include @@ -23,6 +25,8 @@ #include +#include "ring.h" + #ifndef SLIM #include "i2c.h" #endif diff --git a/app/prototypes.h b/app/prototypes.h index c3e7426..cf280b9 100644 --- a/app/prototypes.h +++ b/app/prototypes.h @@ -30,8 +30,56 @@ extern int timed_out(uint32_t then, unsigned int ms); extern void ticker_init(void); /* i2c.c */ /* lcd.c */ -/* cdc.c */ +/* cdcacm.c */ extern const struct usb_interface_descriptor comm_iface[]; extern const struct usb_interface_descriptor data_iface[]; extern int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf, uint16_t *len, int (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)); +extern void cdcacm_data_tx(void *buf, size_t len); extern void cdcacm_data_rx_cb(usbd_device *usbd_dev, uint8_t ep); +/* usart.c */ +extern ring_t rx1_ring; +extern ring_t tx1_ring; +extern ring_t rx2_ring; +extern ring_t tx2_ring; +extern void usart1_isr(void); +extern void usart2_isr(void); +extern int _write(int file, char *ptr, int len); +extern int usart1_tx(void *ptr, int len); +extern int usart2_tx(void *buf, size_t len); +extern void usart1_queue(uint8_t d); +extern void usart2_queue(uint8_t d); +extern void usart2_drain(void); +extern void usart1_drain(void); +extern void usart_init(void); +/* ring.c */ +extern void ring_init(ring_t *r, uint8_t *buf, size_t len); +extern int ring_write_byte(ring_t *r, uint8_t c); +extern int ring_read_byte(ring_t *r, uint8_t *c); +extern int ring_write(ring_t *r, uint8_t *buf, size_t len); +extern int ring_empty(ring_t *r); +/* serial.c */ +extern void serial_poll(void); +/* gpio.c */ +extern void exti15_10_isr(void); +extern void toggle_fake_hook(void); +extern void gpio_tick(void); +extern void gpio_init(void); +/* console.c */ +extern int console_tx(void *buf, size_t len); +/* buzzer.c */ +extern int ringing; +extern void buzzer_on(void); +extern void buzzer_off(void); +extern void buzzer_set_freq(int hz); +extern void buzzer_init(void); +extern void ring_tick(void); +extern void ring_off(void); +extern void ring(int l); +/* modem.c */ +extern void modem_send(char *buf); +extern void modem_line(void); +extern void modem_byte(uint8_t b); +extern void answer_call(void); +extern void terminate_call(void); +extern void modem_tick(void); +extern void modem_init(void); diff --git a/app/ring.c b/app/ring.c new file mode 100644 index 0000000..c4f3458 --- /dev/null +++ b/app/ring.c @@ -0,0 +1,68 @@ +#include "project.h" + + +static inline size_t +ring_next (ring_t * r, size_t p) +{ + p++; + if (p >= r->size) + p -= r->size; + return p; +} + +void +ring_init (ring_t * r, uint8_t * buf, size_t len) +{ + r->data = buf; + r->size = len; + r->write = 0; + r->read = 0; +} + +int +ring_write_byte (ring_t * r, uint8_t c) +{ + size_t n = ring_next (r, r->write); + + if (n == r->read) + return -1; + + r->data[r->write] = c; + + r->write = n; + + return 0; +} + + +int +ring_read_byte (ring_t * r, uint8_t * c) +{ + size_t n = ring_next (r, r->read); + + if (r->read == r->write) + return -1; + + *c = r->data[r->read]; + r->read = n; + + return 0; +} + +int +ring_write (ring_t * r, uint8_t * buf, size_t len) +{ + while (len--) + { + if (ring_write_byte (r, *(buf++))) + return -1; + } + + return 0; +} + +int +ring_empty (ring_t * r) +{ + return (r->read == r->write) ? 1 : 0; +} diff --git a/app/ring.h b/app/ring.h new file mode 100644 index 0000000..ba8887b --- /dev/null +++ b/app/ring.h @@ -0,0 +1,7 @@ +typedef struct ring +{ + uint8_t *data; + size_t size; + size_t write; + size_t read; +} ring_t; diff --git a/app/serial.c b/app/serial.c new file mode 100644 index 0000000..aa67dae --- /dev/null +++ b/app/serial.c @@ -0,0 +1,30 @@ +#include "project.h" + +void serial_poll(void) +{ +uint8_t v; + +if (!ring_read_byte (&rx2_ring, &v)) { +modem_byte(v); +//console_tx(&v,1); +} + +if (!ring_read_byte (&rx1_ring, &v)) { + +if (v=='@') { + toggle_fake_hook(); +} else if (v=='#') { + toggle_fake_hook(); + modem_send("ATDT120;"); +} else { + + usart2_queue(v); +} +} + + + +} + + + diff --git a/app/ticker.c b/app/ticker.c index 84e3e9a..1870a15 100644 --- a/app/ticker.c +++ b/app/ticker.c @@ -31,8 +31,11 @@ sys_tick_handler (void) #ifndef SLIM lcd_tick (); #endif - + gpio_tick(); usb_tick (); + ring_tick(); + modem_tick(); + } diff --git a/app/usart.c b/app/usart.c new file mode 100644 index 0000000..402767d --- /dev/null +++ b/app/usart.c @@ -0,0 +1,227 @@ +#include "project.h" + +#define BUFFER_SIZE 256 +#define BIG_BUFFER_SIZE 600 + +ring_t rx1_ring; +static uint8_t rx1_ring_buf[BUFFER_SIZE]; + +ring_t tx1_ring; +static uint8_t tx1_ring_buf[BUFFER_SIZE]; + +ring_t rx2_ring; +static uint8_t rx2_ring_buf[BUFFER_SIZE]; + +ring_t tx2_ring; +static uint8_t tx2_ring_buf[BIG_BUFFER_SIZE]; + +void +usart1_isr (void) +{ + uint8_t data; + + /* Check if we were called because of RXNE. */ + if (((USART_CR1 (USART1) & USART_CR1_RXNEIE) != 0) && + ((USART_SR (USART1) & USART_SR_RXNE) != 0)) + { + + /* Retrieve the data from the peripheral. */ + data = usart_recv (USART1); + + + ring_write_byte (&rx1_ring, data); + } + + /* Check if we were called because of TXE. */ + if (((USART_CR1 (USART1) & USART_CR1_TXEIE) != 0) && + ((USART_SR (USART1) & USART_SR_TXE) != 0)) + { + + if (ring_read_byte (&tx1_ring, &data)) + { + /*No more data, Disable the TXE interrupt, it's no longer needed. */ + USART_CR1 (USART1) &= ~USART_CR1_TXEIE; + } + else + { + usart_send (USART1, data); + } + } + +} + +void +usart2_isr (void) +{ + uint8_t data; + + /* Check if we were called because of RXNE. */ + if (((USART_CR1 (USART2) & USART_CR1_RXNEIE) != 0) && + ((USART_SR (USART2) & USART_SR_RXNE) != 0)) + { + + /* Retrieve the data from the peripheral. */ + data = usart_recv (USART2); + ring_write_byte (&rx2_ring, data); + + usart1_queue (data); + if (data=='\r') usart1_queue('\n'); + + } + + /* Check if we were called because of TXE. */ + if (((USART_CR1 (USART2) & USART_CR1_TXEIE) != 0) && + ((USART_SR (USART2) & USART_SR_TXE) != 0)) + { + + if (ring_read_byte (&tx2_ring, &data)) + { + /*No more data, Disable the TXE interrupt, it's no longer needed. */ + USART_CR1 (USART2) &= ~USART_CR1_TXEIE; + } + else + { + usart_send_blocking (USART2, data); + usart1_queue (data); + if (data=='\r') usart1_queue('\n'); + } + } + +} + +int +_write (int file, char *ptr, int len) +{ + int ret; + + if (file == 1) + { + ret = ring_write (&tx1_ring, (uint8_t *) ptr, len); + + if (ret < 0) + ret = -ret; + + USART_CR1 (USART1) |= USART_CR1_TXEIE; + return ret; + } + + errno = EIO; + return -1; +} + + +int +usart1_tx (void *ptr, int len) +{ + int ret; + + ret = ring_write (&tx1_ring, (uint8_t *) ptr, len); + + if (ret < 0) + ret = -ret; + + USART_CR1 (USART1) |= USART_CR1_TXEIE; + return ret; +} + + + +int +usart2_tx ( void *buf,size_t len) +{ +int ret; + ret = ring_write (&tx2_ring, buf, len); + + if (ret < 0) + ret = -ret; + + USART_CR1 (USART2) |= USART_CR1_TXEIE; + return ret; +} + + +void +usart1_queue (uint8_t d) +{ + ring_write_byte (&tx1_ring, d); + USART_CR1 (USART1) |= USART_CR1_TXEIE; +} + + +void +usart2_queue (uint8_t d) +{ + ring_write_byte (&tx2_ring, d); + USART_CR1 (USART2) |= USART_CR1_TXEIE; +} + +void +usart2_drain (void) +{ + while (!ring_empty (&tx2_ring)); +} + +void +usart1_drain (void) +{ + while (!ring_empty (&tx1_ring)); +} + + + +void +usart_init (void) +{ + rcc_periph_clock_enable (RCC_USART1); + rcc_periph_clock_enable (RCC_USART2); + + ring_init (&rx1_ring, rx1_ring_buf, sizeof (rx1_ring_buf)); + ring_init (&tx1_ring, tx1_ring_buf, sizeof (tx1_ring_buf)); + + ring_init (&rx2_ring, rx2_ring_buf, sizeof (rx2_ring_buf)); + ring_init (&tx2_ring, tx2_ring_buf, sizeof (tx2_ring_buf)); + + + /* Enable the USART1,2 interrupt. */ + nvic_enable_irq (NVIC_USART1_IRQ); + nvic_enable_irq (NVIC_USART2_IRQ); + + /* Map pins, and set usart2 to have pull ups */ + gpio_set_mode (GPIOA, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART1_TX); + gpio_set_mode (GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, + GPIO_USART1_RX); + gpio_set (GPIOA, GPIO_USART1_RX); + + gpio_set_mode (GPIOA, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART2_TX); + gpio_set_mode (GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, + GPIO_USART2_RX); + gpio_set (GPIOA, GPIO_USART2_RX); + + + /* Setup UART1 parameters. */ + usart_set_baudrate (USART1, 115200); + usart_set_databits (USART1, 8); + usart_set_stopbits (USART1, USART_STOPBITS_1); + usart_set_parity (USART1, USART_PARITY_NONE); + usart_set_flow_control (USART1, USART_FLOWCONTROL_NONE); + usart_set_mode (USART1, USART_MODE_TX_RX); + + /* Setup UART2 parameters. */ + usart_set_baudrate (USART2, 9600); + usart_set_databits (USART2, 8); + usart_set_stopbits (USART2, USART_STOPBITS_1); + usart_set_parity (USART2, USART_PARITY_NONE); + usart_set_flow_control (USART2, USART_FLOWCONTROL_NONE); + usart_set_mode (USART2, USART_MODE_TX_RX); + + + /* Enable USART1,2 Receive interrupt. */ + USART_CR1 (USART1) |= USART_CR1_RXNEIE; + USART_CR1 (USART2) |= USART_CR1_RXNEIE; + + /* Finally enable the USARTs. */ + usart_enable (USART1); + usart_enable (USART2); +} diff --git a/app/usb.c b/app/usb.c index 2bd6986..bf4bbfb 100644 --- a/app/usb.c +++ b/app/usb.c @@ -205,5 +205,6 @@ usb_run (void) for (;;) { usbd_poll (usbd_dev); + serial_poll(); } } diff --git a/doc/SIM800 Series_AT Command Manual_V1.09.pdf b/doc/SIM800 Series_AT Command Manual_V1.09.pdf new file mode 100644 index 0000000..aabadf4 Binary files /dev/null and b/doc/SIM800 Series_AT Command Manual_V1.09.pdf differ -- cgit v1.2.3