|
楼主 |
发表于 2015-12-2 23:20
|
显示全部楼层
移植过程悲喜交加,每每步入迷途时,万能的上帝总能引导我看到花明。
雄心壮志:尽管 arduino已支持arm,包括stm32系列和ATSAM3X8E(arduino Duo),开始想仿照上述系列来改写,粗略看了一下,头都晕了,每个厂商的芯片有其自己的驱动库,如不用驱动,则不但需要了解两种不同芯片的这些寄存器,按功能来改写;如用库,则要找出这些对应的库功能。反正是工程浩大,想想也是,要是简单的话,早就有许多移植版本了。
“天道助勤”:当我想放弃的时候,我在网上发现TI有个类似arduino的开发环境 energia,尽管不直接lm3s811,但毕竟是同一公司产品,驱动库构架和调用方式都是一样,我就选用这个系统的开源部分内容开始我的工作。
放弃energia: 我先搭了个构架,就是在空的core中写两个程序startup.c 和拷贝一个直接寄存器操作的example代码(blink)尝试在energia下编译,看看是否能成,结果打了我一个闷棍,发现在eneria下无法正确生产cortex-m3核心的代码,energia环境下不像 arduno有个platform.txt来定义如何生成代码,规则是内定的(也许我没找到在何处定义的)。
再次尝试:仿照stm32的GCC生成规则,但按energia中的实现方法,移植energia针对LM4F的代码。
又受挫折:并发现:ti许多的arm芯片竟然包含一个内部的rom,把底层驱动的很多核心代码封装好,并提供了一个调用地址定义头文件,而恰恰LM3S811这个廉价芯片是个不含rom的。显然自己不可能写一个兼容rom功能的库!
船到桥头:发现ti提供了一个对应的当无rom或rom功能使替代方案,只要将所有rom调用函数 ROM_XXXXX改为MAP_XXXXXX,这样方便了,
查找替换几分钟就搞定。
要调试核心程序,定义文件是必不可少的,首先是energia.h
energia中也有个arduino.h,其中只有一行代码:
#include ”energia.h"
现在我们来看看这个文件:
[mw_shl_code=bash,true]#ifndef Energia_h
#define Energia_h
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
#include "itoa.h"
#include "part.h"
#include <avr/dtostrf.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#if defined(PART_LM3S811)
//#include "lm3s811.h"
#else
#error "**** No PART defined or unsupported PART ****"
#endif
#include "binary.h"
#include "hw_types.h"
#include "sysctl.h"
#include "hw_nvic.h"
#include "gpio.h"
#ifdef __cplusplus
extern "C"{
#endif
#define NOT_A_PORT 0
#define NOT_A_PIN 0
#define NOT_ON_TIMER 0
#define NOT_ON_ADC 0x10
#define CHANGE 4
#define FALLING 3
#define RISING 2
#define HIGH 0x1
#define LOW 0x0
#define LSBFIRST 0
#define MSBFIRST 1
#define INPUT 0x0
#define OUTPUT 0x1
#define INPUT_PULLUP 0x2
#define INPUT_PULLDOWN 0x3
#define SPI_LAST 0
#define SPI_CONTINUE 1
#define PI 3.1415926535897932384626433832795
#define HALF_PI 1.5707963267948966192313216916398
#define TWO_PI 6.283185307179586476925286766559
#define DEG_TO_RAD 0.017453292519943295769236907684886
#define RAD_TO_DEG 57.295779513082320876798154814105
#define PA 1
#define PB 2
#define PC 3
#define PD 4
#define PE 5
#define PF 6
#define PG 7
#define PH 8
#define PJ 9
#define PK 10
#define PL 11
#define PM 12
#define PN 13
#define PP 14
#define PQ 15
#define PR 16
#define PS 17
#define PT 18
#define TIMA 0
#define TIMB 8
#if defined(__LM3S811__)
#define T0A 0
#define T0B 1
#define T1A 2
#define T1B 3
#define T2A 4
#define T2B 5
#define TIMER0 0
#define TIMER1 1
#define TIMER2 2
#endif
typedef uint8_t boolean;
typedef uint8_t byte;
#define min(a,b) ((a)<(b)?(a)b))
#define max(a,b) ((a)>(b)?(a)b))
#define constrain(amt,low,high) ((amt)<(low)?(low)(amt)>(high)?(high)amt)))
#define round(x) ((x)>=0?(long)((x)+0.5)long)((x)-0.5))
#define radians(deg) ((deg)*DEG_TO_RAD)
#define degrees(rad) ((rad)*RAD_TO_DEG)
#define sq(x) ((x)*(x))
#define interrupts() IntMasterEnable()
#define noInterrupts() IntMasterDisable()
#define clockCyclesPerMicrosecond() (F_CPU / 1000000L )
//#define clockCyclesPerMicrosecond() ( 80000000L / 1000000L )
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
#define lowByte(w) ((uint8_t) ((w) & 0xff))
#define highByte(w) ((uint8_t) ((w) >> 8))
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
typedef unsigned int word;
#define bit(b) (1UL << (b))
void init(void);
void setup(void);
void loop(void);
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder);
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout);
void pinMode(uint8_t, uint8_t);
void digitalWrite(uint8_t, uint8_t);
int digitalRead(uint8_t);
void digitalToggle(uint8_t pin); //add by huawei
uint16_t analogRead(uint8_t);
void analogWrite(uint8_t, int);
void analogReference(uint16_t);
void analogFrequency(uint32_t);
void analogResolution(uint16_t);
void delay(uint32_t milliseconds);
/* void sleep(uint32_t milliseconds);
void sleepSeconds(uint32_t seconds);
void suspend(void);
extern volatile boolean stay_asleep;
#define wakeup() { stay_asleep = false; }
*/
void attachInterrupt(uint8_t, void (*)(void), int mode);
void detachInterrupt(uint8_t);
extern const uint8_t digital_pin_to_timer[];
extern const uint8_t digital_pin_to_port[];
extern const uint8_t digital_pin_to_bit_mask[];
extern const uint32_t timer_to_offset[];
extern const uint8_t timer_to_ab[];
extern const uint32_t timer_to_pin_config[];
extern const uint32_t port_to_base[];
extern const uint32_t digital_pin_to_analog_in[];
#define digitalPinToPort(P) ( digital_pin_to_port[P] )
#define digitalPinToBitMask(P) ( digital_pin_to_bit_mask[P] )
#define digitalPinToTimer(P) ( digital_pin_to_timer[P] )
#define analogInPinToBit(P) (P) //add by hw
#define timerToAB(P) ( timer_to_ab[P] )
#define timerToOffset(P) ( timer_to_offset[P] )
#define timerToPinConfig(P) ( timer_to_pin_config[P] )
#define digitalPinToADCIn(P) (((P)<NUM_ANALOG_INPUTS)? digital_pin_to_analog_in[P]:NOT_ON_ADC)
#define portBASERegister(P) ((volatile uint32_t *) port_to_base[P])
#define portDATARegister(P) ((volatile uint32_t *)( port_to_base[P] + 0x3FC ))
#define portDIRRegister(P) ((volatile uint32_t *)( port_to_base[P] + 0x400 ))
#define portIBERegister(P) ((volatile uint32_t *)( port_to_base[P] + 0x408 ))
#define portIEVRegister(P) ((volatile uint32_t *)( port_to_base[P] + 0x40C ))
#define portIMRegister(P) ((volatile uint32_t *)( port_to_base[P] + 0x410 ))
#define portRISRegister(P) ((volatile uint32_t *)( port_to_base[P] + 0x414 ))
#define portMISRegister(P) ((volatile uint32_t *)( port_to_base[P] + 0x418 ))
#define portICRRegister(P) ((volatile uint32_t *)( port_to_base[P] + 0x41C ))
#define portAFSELRegister(P) ((volatile uint32_t *)( port_to_base[P] + 0x420 ))
#define portDR2RRegister(P) ((volatile uint32_t *)( port_to_base[P] + 0x500 ))
#define portDR4RRegister(P) ((volatile uint32_t *)( port_to_base[P] + 0x504 ))
#define portDR8RRegister(P) ((volatile uint32_t *)( port_to_base[P] + 0x508 ))
#define portODRRegister(P) ((volatile uint32_t *)( port_to_base[P] + 0x50C ))
#define portPURRegister(P) ((volatile uint32_t *)( port_to_base[P] + 0x510 ))
#define portPDRRegister(P) ((volatile uint32_t *)( port_to_base[P] + 0x514 ))
#define portSLRRegister(P) ((volatile uint32_t *)( port_to_base[P] + 0x518 ))
#define portDENRegister(P) ((volatile uint32_t *)( port_to_base[P] + 0x51C ))
/*#define portLOCKRegister(P) ((volatile uint32_t *)( port_to_base[P] + 0x520 ))
#define portCRRegister(P) ((volatile uint32_t *)( port_to_base[P] + 0x524 ))
#define portAMSELRegister(P) ((volatile uint32_t *)( port_to_base[P] + 0x528 ))
#define portPCTLRegister(P) ((volatile uint32_t *)( port_to_base[P] + 0x52C ))
#define portADCCTLRegister(P) ((volatile uint32_t *)( port_to_base[P] + 0x530 ))
#define portMACTLRegister(P) ((volatile uint32_t *)( port_to_base[P] + 0x534 ))
#define portPeriphID4Register(P) ((volatile uint32_t *)( port_to_base[P] + 0xFD0 ))
#define portPeriphID5Register(P) ((volatile uint32_t *)( port_to_base[P] + 0xFD4 ))
#define portPeriphID6Register(P) ((volatile uint32_t *)( port_to_base[P] + 0xFD8 ))
#define portPeriphID7Register(P) ((volatile uint32_t *)( port_to_base[P] + 0xFDC ))
#define portPeriphID0Register(P) ((volatile uint32_t *)( port_to_base[P] + 0xFE0 ))
#define portPeriphID1Register(P) ((volatile uint32_t *)( port_to_base[P] + 0xFE4 ))
#define portPeriphID2Register(P) ((volatile uint32_t *)( port_to_base[P] + 0xFE8 ))
#define portPeriphID3Register(P) ((volatile uint32_t *)( port_to_base[P] + 0xFEC ))
#define portCellID0Register(P) ((volatile uint32_t *)( port_to_base[P] + 0xFF0 ))
#define portCellID1Register(P) ((volatile uint32_t *)( port_to_base[P] + 0xFF4 ))
#define portCellID2Register(P) ((volatile uint32_t *)( port_to_base[P] + 0xFF8 ))
#define portCellID3Register(P) ((volatile uint32_t *)( port_to_base[P] + 0xFFC ))
*/
// Implemented in wiring.c
void delayMicroseconds(unsigned int us);
unsigned long micros();
unsigned long millis();
void timerInit();
void registerSysTickCb(void (*userFunc)(uint32_t));
#ifdef __cplusplus
} // extern "C"
#endif
#ifdef __cplusplus
#include "WCharacter.h"
#include "WString.h"
#include "HardwareSerial.h"
uint16_t makeWord(uint16_t w);
uint16_t makeWord(byte h, byte l);
#define word(...) makeWord(__VA_ARGS__)
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
void tone(uint8_t _pin, unsigned int frequency);
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration);
void noTone(uint8_t _pin);
// WMath prototypes
long random(long);
long random(long, long);
void randomSeed(unsigned int);
long map(long, long, long, long, long);
#endif
#include "pins_energia.h"
#endif
[/mw_shl_code]
其中 188~205代码在LM3s811中无用,直接/* */掉了。
下次引脚(pin)定义文件:pins_energia.h(待续)
|
|