diff options
author | root <root@lamia.panaceas.james.local> | 2016-08-20 20:55:43 +0100 |
---|---|---|
committer | root <root@lamia.panaceas.james.local> | 2016-08-20 20:55:43 +0100 |
commit | e696ed2427fe036a0dcfe50f209e22a9f273d100 (patch) | |
tree | 837ac9421102a7b83a4d55b72e22fce5f6033214 | |
parent | b063a2da3024a2e3175e1ba9b0a87cb6c7470765 (diff) | |
download | candlestick-e696ed2427fe036a0dcfe50f209e22a9f273d100.tar.gz candlestick-e696ed2427fe036a0dcfe50f209e22a9f273d100.tar.bz2 candlestick-e696ed2427fe036a0dcfe50f209e22a9f273d100.zip |
working calls
-rw-r--r-- | app/Makefile | 3 | ||||
-rw-r--r-- | app/buzzer.c | 143 | ||||
-rw-r--r-- | app/cdcacm.c (renamed from app/cdc.c) | 13 | ||||
-rw-r--r-- | app/console.c | 17 | ||||
-rw-r--r-- | app/gpio.c | 86 | ||||
-rw-r--r-- | app/led.c | 2 | ||||
-rw-r--r-- | app/main.c | 27 | ||||
-rw-r--r-- | app/modem.c | 99 | ||||
-rw-r--r-- | app/project.h | 6 | ||||
-rw-r--r-- | app/prototypes.h | 50 | ||||
-rw-r--r-- | app/ring.c | 68 | ||||
-rw-r--r-- | app/ring.h | 7 | ||||
-rw-r--r-- | app/serial.c | 30 | ||||
-rw-r--r-- | app/ticker.c | 5 | ||||
-rw-r--r-- | app/usart.c | 227 | ||||
-rw-r--r-- | app/usb.c | 1 | ||||
-rw-r--r-- | doc/SIM800 Series_AT Command Manual_V1.09.pdf | bin | 0 -> 3221609 bytes |
17 files changed, 772 insertions, 12 deletions
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; +} + + + + @@ -139,16 +139,17 @@ int cdcacm_control_request(usbd_device *usbd_dev, 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) { - buf[0]^=32; - usbd_ep_write_packet(usbd_dev, 0x82, buf, len); - buf[len] = 0; - } + 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); + +} @@ -43,5 +43,7 @@ led_tick (void) else gpio_set (GPIOC, GPIO13); + + } @@ -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<SLEEPY) +sleepy++; + +if (!timeout) return; +timeout--; +if (timeout) return; + +modem_send(modem_cmd); +} + +void modem_init(void) { +} diff --git a/app/project.h b/app/project.h index 0b1a26d..359b290 100644 --- a/app/project.h +++ b/app/project.h @@ -7,11 +7,13 @@ #include <libopencm3/stm32/adc.h> #include <libopencm3/stm32/usart.h> #include <libopencm3/stm32/usb.h> +#include <libopencm3/stm32/exti.h> +#include <libopencm3/stm32/timer.h> #include <libopencm3/cm3/systick.h> #include <libopencm3/cm3/nvic.h> +#include <libopencm3/cm3/cortex.h> #include <libopencm3/usb/usbd.h> #include <libopencm3/usb/cdc.h> -#include <libopencm3/cm3/cortex.h> #include <stm32f101cb_clock.h> #include <string.h> @@ -23,6 +25,8 @@ #include <errno.h> +#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); +} @@ -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 Binary files differnew file mode 100644 index 0000000..aabadf4 --- /dev/null +++ b/doc/SIM800 Series_AT Command Manual_V1.09.pdf |