mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-22 12:28:03 +08:00
This commit is contained in:
@@ -24,9 +24,9 @@
|
||||
|
||||
#include "gsm.h"
|
||||
#include "std.h"
|
||||
#include "uart.h"
|
||||
#include "downlink.h"
|
||||
|
||||
#define GSM_LINK Uart0
|
||||
#define GSM_LINK Uart3100
|
||||
#define GSM_MAX_PAYLOAD 160
|
||||
|
||||
#define __GSMLink(dev, _x) dev##_x
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2009 ENAC
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi 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 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LPC21xx.h"
|
||||
#include "interrupt_hw.h"
|
||||
#include "max3100_hw.h"
|
||||
#include "led.h"
|
||||
|
||||
uint8_t max3100_status;
|
||||
bool max3100_data_available;
|
||||
|
||||
uint8_t max3100_tx_insert_idx, max3100_tx_extract_idx;
|
||||
uint8_t max3100_rx_insert_idx, max3100_rx_extract_idx;
|
||||
|
||||
uint8_t max3100_tx_buf[MAX3100_TX_BUF_LEN];
|
||||
uint8_t max3100_rx_buf[MAX3100_RX_BUF_LEN];
|
||||
|
||||
|
||||
static void EXTINT0_ISR(void) __attribute__((naked));
|
||||
static void SPI1_ISR(void) __attribute__((naked));
|
||||
|
||||
|
||||
void max3100_init( void ) {
|
||||
|
||||
max3100_status = MAX3100_STATUS_IDLE;
|
||||
max3100_data_available = false;
|
||||
max3100_tx_insert_idx = 0;
|
||||
max3100_tx_extract_idx = 0;
|
||||
max3100_rx_insert_idx = 0;
|
||||
max3100_rx_extract_idx = 0;
|
||||
|
||||
/* From arm7/max1167_hw.c */
|
||||
|
||||
/* SS pin is output */
|
||||
SetBit(MAX3100_SS_IODIR, MAX3100_SS_PIN);
|
||||
/* unselected max3100 */
|
||||
Max3100Unselect();
|
||||
|
||||
/* connect P0.16 to extint0 (IRQ) */
|
||||
MAX3100_IRQ_PINSEL |= MAX3100_IRQ_PINSEL_VAL << MAX3100_IRQ_PINSEL_BIT;
|
||||
/* extint0 is edge trigered */
|
||||
SetBit(EXTMODE, MAX3100_IRQ_EINT);
|
||||
/* extint0 is trigered on falling edge */
|
||||
ClearBit(EXTPOLAR, MAX3100_IRQ_EINT);
|
||||
/* clear pending extint0 before enabling interrupts */
|
||||
SetBit(EXTINT, MAX3100_IRQ_EINT);
|
||||
|
||||
/* Configure interrupt vector for external pin interrupt */
|
||||
VICIntSelect &= ~VIC_BIT( VIC_EINT0 ); // EXTINT0 selected as IRQ
|
||||
VICIntEnable = VIC_BIT( VIC_EINT0 ); // EXTINT0 interrupt enabled
|
||||
VICVectCntl8 = VIC_ENABLE | VIC_EINT0;
|
||||
VICVectAddr8 = (uint32_t)EXTINT0_ISR; // address of the ISR
|
||||
|
||||
/* Configure interrupt vector for SPI */
|
||||
VICIntSelect &= ~VIC_BIT(VIC_SPI1); /* SPI1 selected as IRQ */
|
||||
VICIntEnable = VIC_BIT(VIC_SPI1); /* SPI1 interrupt enabled */
|
||||
VICVectCntl7 = VIC_ENABLE | VIC_SPI1;
|
||||
VICVectAddr7 = (uint32_t)SPI1_ISR; /* address of the ISR */
|
||||
|
||||
/* Write configuration */
|
||||
Max3100TransmitConf(MAX3100_BAUD_RATE | MAX3100_BIT_NOT_RM);
|
||||
}
|
||||
|
||||
|
||||
void EXTINT0_ISR(void) {
|
||||
ISR_ENTRY();
|
||||
|
||||
max3100_data_available = true;
|
||||
|
||||
SetBit(EXTINT, MAX3100_IRQ_EINT); /* clear extint0 */
|
||||
VICVectAddr = 0x00000000; /* clear this interrupt from the VIC */
|
||||
|
||||
ISR_EXIT();
|
||||
}
|
||||
|
||||
void SPI1_ISR(void) {
|
||||
uint8_t read_byte;
|
||||
|
||||
ISR_ENTRY();
|
||||
|
||||
Max3100Unselect();
|
||||
max3100_status = MAX3100_STATUS_IDLE;
|
||||
|
||||
switch (max3100_status) {
|
||||
case MAX3100_STATUS_READING:
|
||||
SpiRead(read_byte);
|
||||
SpiRead(max3100_rx_buf[max3100_rx_insert_idx]);
|
||||
max3100_rx_insert_idx++; // automatic overflow because len=256
|
||||
max3100_data_available = Max3100BitR(read_byte);
|
||||
break;
|
||||
|
||||
case MAX3100_STATUS_WRITING:
|
||||
SpiRead(read_byte);
|
||||
SpiRead(read_byte);
|
||||
break;
|
||||
}
|
||||
|
||||
VICVectAddr = 0x00000000; /* clear this interrupt from the VIC */
|
||||
ISR_EXIT();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void max3100_test_write( void ) {
|
||||
max3100_putchar('a');
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
#ifndef MAX3100_H
|
||||
#define MAX3100_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "std.h"
|
||||
#include "spi_hw.h"
|
||||
|
||||
/* Pin configuration for max3100 IRQ */
|
||||
#define MAX3100_IRQ_PIN 16
|
||||
#define MAX3100_IRQ_PINSEL PINSEL1
|
||||
#define MAX3100_IRQ_PINSEL_BIT 0
|
||||
#define MAX3100_IRQ_PINSEL_VAL 1
|
||||
#define MAX3100_IRQ_EINT 0
|
||||
#define MAX3100_SS_PORT 0
|
||||
#define MAX3100_SS_PIN 20
|
||||
|
||||
#define MAX3100_IO__(port, reg) IO ## port ## reg
|
||||
#define MAX3100_IO_(port, reg) MAX3100_IO__(port, reg)
|
||||
|
||||
#define MAX3100_SS_IOCLR MAX3100_IO_(MAX3100_SS_PORT, CLR)
|
||||
#define MAX3100_SS_IODIR MAX3100_IO_(MAX3100_SS_PORT, DIR)
|
||||
#define MAX3100_SS_IOSET MAX3100_IO_(MAX3100_SS_PORT, SET)
|
||||
|
||||
/** Max3100 protocol status */
|
||||
#define MAX3100_STATUS_IDLE 0
|
||||
#define MAX3100_STATUS_WRITING 1
|
||||
#define MAX3100_STATUS_READING 2
|
||||
|
||||
extern uint8_t max3100_status;
|
||||
extern bool max3100_data_available;
|
||||
|
||||
/** I/O Buffers */
|
||||
#define MAX3100_TX_BUF_LEN 256
|
||||
#define MAX3100_RX_BUF_LEN 256
|
||||
|
||||
extern uint8_t max3100_tx_insert_idx, max3100_tx_extract_idx;
|
||||
extern uint8_t max3100_rx_insert_idx, max3100_rx_extract_idx;
|
||||
|
||||
extern uint8_t max3100_tx_buf[MAX3100_TX_BUF_LEN];
|
||||
extern uint8_t max3100_rx_buf[MAX3100_RX_BUF_LEN];
|
||||
|
||||
#define Max3100Select() { \
|
||||
SetBit(MAX3100_SS_IOCLR, MAX3100_SS_PIN); \
|
||||
}
|
||||
|
||||
#define Max3100Unselect() { \
|
||||
SetBit(MAX3100_SS_IOSET, MAX3100_SS_PIN); \
|
||||
}
|
||||
|
||||
#define MAX3100_WRITE_CONF ((1U<<15) | (1U<<14))
|
||||
#define MAX3100_READ_CONF ((0U<<15) | (1U<<14))
|
||||
#define MAX3100_WRITE_DATA ((1U<<15) | (0U<<14))
|
||||
#define MAX3100_READ_DATA ((0U<<15) | (0U<<14))
|
||||
|
||||
#define MAX3100_BAUD_RATE_19200 0x9
|
||||
#define MAX3100_BAUD_RATE_9600 0xA
|
||||
|
||||
#define MAX3100_BIT_NOT_RM (1U<<10)
|
||||
#define MAX3100_BIT_NOT_TM (1U<<11)
|
||||
#define MAX3100_BIT_NOT_FEN (1U<<13)
|
||||
#define Max3100BitR(_conf_byte) ((_conf_byte)>>7)
|
||||
|
||||
/** Like Uart macros */
|
||||
#define Uart3100Init() max3100_init()
|
||||
#define Uart3100CheckFreeSpace(_x) (((int16_t)max3100_tx_extract_idx - max3100_tx_insert_idx + MAX3100_TX_BUF_LEN) % MAX3100_TX_BUF_LEN >= 1)
|
||||
#define Uart3100Transmit(_x) max3100_putchar(_x)
|
||||
#define Uart3100SendMessage() {}
|
||||
#define Uart3100Getch() ({\
|
||||
uint8_t ret = max3100_rx_buf[max3100_rx_extract_idx]; \
|
||||
max3100_rx_extract_idx++; /* Since size=256 */ \
|
||||
ret; \
|
||||
})
|
||||
|
||||
#define Uart3100ChAvailable() (max3100_rx_extract_idx != max3100_rx_insert_idx)
|
||||
|
||||
static inline void max3100_transmit(uint16_t data) {
|
||||
SSPDR = data >> 8;
|
||||
SSPDR = data & 0xff;
|
||||
SpiClrCPHA(); /* Data captured on first clock edge transition */
|
||||
Max3100Select();
|
||||
SpiEnable();
|
||||
}
|
||||
|
||||
#define Max3100TransmitConf(_conf) max3100_transmit((_conf) | MAX3100_WRITE_CONF)
|
||||
#define Max3100TransmitData(_data) max3100_transmit((_data) | MAX3100_WRITE_DATA)
|
||||
#define Max3100ReadData() max3100_transmit(MAX3100_READ_DATA)
|
||||
|
||||
|
||||
static inline void max3100_read_data(void) {
|
||||
Max3100ReadData();
|
||||
max3100_status = MAX3100_STATUS_READING;
|
||||
}
|
||||
|
||||
static inline void max3100_flush( void ) {
|
||||
if (max3100_status == MAX3100_STATUS_IDLE
|
||||
&& max3100_tx_extract_idx != max3100_tx_insert_idx) {
|
||||
Max3100TransmitData(max3100_tx_buf[max3100_tx_extract_idx]);
|
||||
max3100_tx_extract_idx++; /* automatic overflow since len=256 */
|
||||
max3100_status == MAX3100_STATUS_WRITING;
|
||||
}
|
||||
}
|
||||
|
||||
/** Warning: No bufferring; SPI must be available */
|
||||
static inline void max3100_putconfchar(char c) {
|
||||
Max3100TransmitConf(c);
|
||||
max3100_status = MAX3100_STATUS_WRITING;
|
||||
}
|
||||
|
||||
static inline void max3100_putchar(char c) {
|
||||
max3100_tx_buf[max3100_tx_insert_idx] = c;
|
||||
max3100_tx_insert_idx++; /* automatic overflow since len=256 */
|
||||
/* flushed in the next event */
|
||||
}
|
||||
|
||||
extern void max3100_init( void );
|
||||
extern void max3100_test_write( void );
|
||||
|
||||
static inline void max3100_event( void ) {
|
||||
if (max3100_status == MAX3100_STATUS_IDLE) {
|
||||
if (max3100_data_available)
|
||||
max3100_read_data();
|
||||
else
|
||||
max3100_flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* MAX3100_H */
|
||||
Reference in New Issue
Block a user