原创 LM3S3748的评估及开发过程之感触

2009-10-7 09:56 6359 15 15 分类: MCU/ 嵌入式


LM3S3748的评估及开发过程之感触

 



注:本文仅代表本人的评估观点!类似“无责任书评”吧。


本文全文下载



 



最近,有几个设计项目需求都是要求在嵌入式项目中实现USB DeviceUSB Host功能的。尤其是3G数据交换平台的方案更是要求,用到有USB Host功能的MCU来驱动3G
Modem
模块。当然,传统的MCU的方案也不少,S3C2410就是典型的例子。可是S3C2410从系统价格(整体BOM还是偏高一些)到生产(BGA焊接)对于一些产品来说还是有些困难。



 



凑巧有Luminary的代理商到我这里来推荐新的CortexM3系列MCU。当介绍到LM3S3xxx功能时,它的USB接口功能使我眼前一亮:



50MHzCortexM3,约等于传统的60MIPS



USB接口可以配置为DeviceHost功能。



演示及开发系统功能完善,有完整的USB 库。



另外,我曾经参与过别的朋友的项目。他们就是用LM3S1xx系列实现的产品,从他们开发的过程看,这系列的MCU对开发系统要求简单。而且,Luminary结构清晰的RDK API分层方式,也是大多数嵌入式开发人员所推崇的。况且他们的那款使用Luminary
MCU
的产品已经量产。



嗯,这款MCU值得一弄呀!



通过关系,弄来了原装的LM3S3748
EVB
板。精致的塑料盒外包装,打开来一看:有个带LCD的屏的开发板,USB线,一支评估用的U盘,还有评估软件光盘。



安装好光盘的内容,里面的信息还是很全呀,从RDKANDatasheet都有。



先看Datasheet吧,功能都了解一下。这次只要关注接口功能和电源管理两个方面。各方面指标都很满意。尤其是电源管理方面应该是这款MCU的亮点。



点击看大图



点击看大图



重点参考Datasheet的第7章,Hibernation Module部分:



点击看大图



LM3S3748系统电源管理设计简单,MCU只要求IO电源VDD=3.3VCore电源VDD25=2.5V,模拟ADC部分电源VDDA=3.3V,后备电池电源VBAT=3V



LM3S3748Run ModeSleep ModeDeep Sleep ModeHibernate Mode四种工作模式。从下表来看,功耗完全符合一般锂电池供电手持式设备的功耗要求。系统进入Hibernate Mode后,HIB输出低,将系统电源的En端拉低,内部只由RTC部分工作。由外部后备电池供电。系统要重新启动,只要将WAKE拉低。HIB就会输出高,系统重新上电,复位。看起来很简单呀!(各位问题就会出在这里,继续关注我的体会吧)。



 



以下是我几天中学习RDK的一些笔记。当然在开发板上跑例程和USB功能就不用多说了,一切都很顺利。刷LCD也很方便,RDK都整理好了。SSI接口有SPI模式,可以驱动T-Flash卡。而且还在EVB上面跑了uC/OS-II的例程。Luminary的文档功夫确实让咱们佩服。



 



LM3S3748



封装 :参考Datasheet P674  LQFP-100



GPIO: 参考Datasheet P250  PA0~7,
PB0~7,PC0~7,PD0~7,PE0~7,PF0~7,PG0~7,PH0~3



40GPIO



USB 接口: 参考Datasheet P503



支持USB 2.0 Full-speed Host or Device



Three configurable endpoints(1-3) with a
dynamic sizable FIFO support multiple packet queueing.(3 receive and 3 transmit
configurable endpoints)



1 dedicated bi-directional control endpoint



4KB dedicated endpoint memory



DMA access to the FIFO allows minimal
interference from system software.



 



学习步骤:



1.       
研究LM3S3748 Driver Library包,



ROM_xxx() 表示利用芯片内部ROM Table中包含的函数,这样可以减少对Flash空间的占用。



也可以使用MAP_xxx()对代码进行Complie-time自动配置,如果芯片内部有ROM 则编译时将MAP_xxx()函数自动编译为ROM_xxx()函数;如果芯片内部无ROM则将MAP_xxx()函数编译为Flash空间中的xxx()函数。



参考
PDL_LM3S-UG-3047.pdf P330
Mapped
ROM Calls



 



2.       
EK-LM3S3748_EvalBoard
User’s Guide



EVBLM3S3748的程序下载是通过FIDIUSB接口,通过FIDIUARTLM3S3748Uart0连接。实现从Uart0下载的。???



 



参考 EK-LM3S3748_EvalBoard.pdf P26 VCP_RX,VCP_TX信号。



   可以使用工具:LM Flash Programmer



 



         从原理图上看是通过FIDI的输出的JTAG,再经过CPLD,将JTAG转给LM3S3748的。



         通过Keil
C
选择



         EVB上的USB接口上有个模拟开关。开关的切换用PH2控制(不是PB0)。



HOSTEn Low= USB Host selected



HOSTEn High USB
Device selected



 



3.       
USB部分



USB Library 参考 PDL-USBL-UG-3047.pdf



包括四类函数集:



     
Device
Host应用都会用到的通用目的函数。这些函数包括解析USB Descriptors 和设置应用下的操作模式的函数。



     
Device设备会用到的不依赖设备类特性的函数。例如,Host信号连接及标准Descriptor相应。



     
Host
设备会用到的不依赖设备类特性的函数。例如,Device设备检测及媒举,端点管理。



     
帮助特定USB类设备开发的特定类函数(Class specific functions)和数据类型(data
types
)。



 



PDL_LM3S-UG-3047.pdf
LM3S DriverLibrary 应用指南。



LM3SUSB controller对应的角色:DeviceUSBDev),HostUSBHost),OTGUSBOTG),USBEndpointUSBFIFO



 



首先要熟悉BootCode,参考PDL-LM3S-UG-3047.pdf  P17 Boot
Code”



Keil开发环境下,BootCodeStartup.S文件中。在这个文件中,我们必须分配中断句柄 Interrupt handler 给相关的中断函数。



参考下面的代码:



;******************************************************************************



;



; External
declarations for the interrupt handlers used by the application.



;



;******************************************************************************



        EXTERN 
IntGPIOa    
;要在其它.c 文件中实现IntGPIOa
中断函数



        EXTERN 
IntGPIOb    
;要在其它.c 文件中实现IntGPIOb
中断函数



        EXTERN 
IntGPIOc    
;要在其它.c 文件中实现IntGPIOc
中断函数



 



Using USB with
the uDMA Controller



uDMA 控制器不能访问控制端点0,其它端点都可以访问。



注意:



USB host IN and
USB device OUT
端点都使用uDMA 接收(receive)
Channel;

USB host OUT and UsB device IN
端点都使用uDMA
发送(transmit) Channel.



在配置端点的同时也需要配置DMA



 



USB Controller应用: P285



DriverLib\usblib 下是USB部分的驱动源码。



 



Luminary USB相关的驱动API函数分为不同级别的4层:



     
Device
Class APIs



     
Device
Class Driver APIs



     
The
USB Device API



     
The
USB DriverLib API



 



点击看大图



USB DriverLib
API



USB DriverLibUSB设备栈的最底层,全部的源码都在usb.cusb.h中。由于DriverLib APIUSB
Controller
硬件寄存器上包的最薄的一层API,因此没有提供任何高层的USB传输支持(例如,端点0传输处理,标准描述符及请求处理,等等)。这层API不适合作应用程序接口。但是很适合用这层API作适合的接口,例如,第三方的USB协议栈。



 



USB Device API



         USB Device API提供了允许开发全特性USB Device应用的一组函数。这些函数多是设备类不相关的。USB Device API支持通过从主机发出的标准请求实现设备媒举。



USB Device API可以用来开发USB设备类驱动。当开发USB Device API时,有时也必须调用USB DriverLib API



USB Device API的头文件在device/usbdevice.h



Qs-scope 例程就是应用USB
Device API
Windows PC上的应用通讯。



 



USB Device Class
Driver APIs



         Device Class Driver提供了一种高层的USB函数。这些函数在不用考虑USB传输控制的情况下提供一定的USB特性。这些驱动为常用的USB 设备类提供了具有以下特性的高层API函数:



     
容易使用。设备的建立紧调用一系列静态的数据结构而且仅需要调用一个初始API



     
可轻松客户化定制VID/PID,电源参数和字符串表,不用修改任何的库代码。



     
一致的接口。所用的设备类驱动都使用同样的API。这样在各设备类间切换就非常方便了。



     
最少的应用扩展。???



     
可以使用可选的USB Buffer对象来更简化数据传输和接收。使用USB BuffersDevice Class Driver交互可以使其变得像读写API一样简单。而不用考虑用状态机来确认数据是被传输了还是正在发送。



     
Device
Class Driver API
完全覆盖了下层的USB DeviceUSB Driver API,因此在应用开发时只需要一个简单的API接口。



 



了解了以上的信息,应用开发者在使用Device Classs Driver API时更要注意下面的限制:



     
在应用中仅允许出现一个Device Class Driver



     
现有的class driver 不支持复合设备。如果应用希望支持多于一个USB Class就必须直接调用USB Device API。或者是参考现有的Class Drivers再开发一个复合需要的、Class Driers



     
目前提供的device class drivers不支持转化配置信息。



 



目前提供的Device Class Driver支持创建通用的Bulk设备,Communication
Device Class(virtual serial port)device

Human Interface Device Class device
mouse,
keyboard
joysticketc



 



 



参考PDL-USBL-UG-3047.pdf P134 Using the USB Device API



来写一个USB Mass storge Device设备



 



         如果现有的USB
Device Class Driver
不能适合你的应用,就需要用更底层的USB Device APIUSB Device API会更灵活的解决更多的问题。使用USB Device API创建一个设备应用会经历下面几步:



     
创建 Device,configurationinterfaceendpoint
描述符结构来描述你的设备



     
为你的设备从USB library 接收的每个关心的USB events写事件句柄(Handler)函数



     
调用USB Device API 将设备连接到总线并且管理标准的Host交互。



 



USB Device API开发相关的几个资源的应用要弄清楚:



1. 描述符如何创建,描述符如何被USB Library调用?



2. USB Buffer 如何分配?



3. USB Event如何理解?各类事件的句柄是如何关联的?



4. uDMA是如何初始化及操作的?



 



 



第一步,创建描述符(Building Descriptors



         tDeviceInfo定义:



typedef struct





         tCustomHandlers sCallbacks;



const unsigned char * pDeviceDescriptor;



const tConfigHeader
*const *ppConfigDescriptors;



const unsigned char *const *ppStringDescriptors;



unsigned long ulNumStringDescriptors;



const tFIFOConfig *psFIFOConfig;



tDeviceInfo





         USB Device API管理所有标准USB描述符。这些描述符通过tDeviceInfo机构中的四个数据域提供给LibraryUSBDCDInit()会调用tDeviceInfo。相关的数据域是:



     
pDeviceDescriptor



     
ppConfigDescriptors



     
ppStringDescriptors



     
ulNumStringDescriptos



所有的描述符都以指针的形式指向unsigned Character类型的数组。对于特定的描述符的例程可以参考每个USB device class driver主程序源文件(例如,对于generic bulk device class driver 可以参考device/usbdbulk.c)或者在qs-scope
应用例程中的usbdescriptors.c



tDeviceInfo.pDeviceDescriptor



这个数组保存了USB
Device API
返回给HostGET_DESCRIPTOR(DEVICE)请求的device descriptor。下面是USB
Masstorage device
device descriptor例程:



const unsigned char g_pDeviceDescriptor[]=



{



    18,                         // Size of this
structure.



   
USB_DTYPE_DEVICE,       // Type of
this structure.



   
USBShort(0x200),            // USB
version 2.0



    0,                          // USB Device Class



    0,                          // USB Device
Sub-class



    0,                          // USB Device
protocol



    64,                         // Maximum packet size
for default pipe.



   
USBShort(0x7104),           //
Vendor ID (VID).



    USBShort(0xf0ff),            // Product ID (PID).



   
USBShort(0x100),            //
Device Version BCD.



    1,                          // Manufacturer
string identifier.



0,                          // Product string
identifier.



2,                          // Product serial
number.



1                           // Number of
configurations





描述符结构中用到的宏定义和标号包含在usblib.h头文件或特定的device
class
头文件,例如:usbhid.hdevice/usbhid.h 头文件包含HID
类中的特定值。



 



tDeviceInfo.ppConfigDescriptors



           相对于一个设备描述符而言,多个配置描述符需要通过ppConfigDescriptors指向一个指向tConfigHeader结构的指针数组。pDeviceDescriptor 域中的最后一项定义了配置的数量。



           为了更灵活的定义复合设备,不同的配置描述符也定义在一个结构数组中(tConfigHeader)。tConfigHeader结构由数量和一个指向tConfigSection结构数组组成。



typedef struct



{



           unsigned
char ucNumSections;



     const tConfigSection *const *psSections;



}tConfigHeader



 



typedef struct



{



           unsigned
char ucSize;



     const
unsigned char *pucData;       //A pointer to a block of data containing an intergral
number of USB descriptors which form part of a larger configuration descriptor;



}tConfigSection



 



tConfigSection 真正包含了要向Host反馈的配置描述符信息。



下面的例程提供了一个USB Mass Storage Device 的配置描述符结构。这个例程提供了一个包含一个接口和使用两个BULK端点(一个IN,一个OUT)的单一配置。



在本例程中,我们说明了如何使用多个Section去构建一个配置描述符。



注意,描述符域中的wTotalLength 中的值无需准确,因为在最终Build 描述符时USB library会根据Section中的内容自动计算这个值。



 



const unsigned char g_pMscConfigDescriptor[] =



{



    //



    //
Configuration descriptor header.



    //



    9,                          // Size of the
configuration descriptor.



   
USB_DTYPE_CONFIGURATION,    //
Type of this descriptor.



    USBShort(32),               // The total size of this full
structure.



    1,                          // The number of
interfaces in this



                                //
configuration.



    1,                          // The unique value
for this configuration.



    0,                          // The string
identifier that describes this



                                //
configuration.



    0x80,                       // Bus Powered, Self
Powered, remote wakeup.



    0xC8,                       // The maximum power in 2mA
increments.



 



    //



    //
Vendor-specific Interface Descriptor.



    //



    9,                          // Size of the
interface descriptor.



   
USB_DTYPE_INTERFACE,        //
Type of this descriptor.



    0,                          // The index for this
interface.



    0,                          // The alternate
setting for this interface.



    2,                          // The number of
endpoints used by this



                                // interface.



    0x08,                   // The interface class   USB Mass Storage



    0x06,                   // The interface sub-class. 使用的子类,为简化块命令



    0x50, // The
interface protocol for the sub-class
使用的协议,这里使用单批量传输协议



                                // specified
above.



    0,                          // The string index
for this interface.



 



    //



    // Endpoint
Descriptor



    //



    7,                               // The size of
the endpoint descriptor.



   
USB_DTYPE_ENDPOINT,             
// Descriptor type is an endpoint.



   
USB_EP_DESC_IN | USB_EP_TO_INDEX(DATA_IN_ENDPOINT),



   
USB_EP_ATTR_BULK,               
// Endpoint is a bulk endpoint.



   
USBShort(DATA_IN_EP_MAX_SIZE),  
// The maximum packet size. 64bytes



    0,                               // The polling
interval for this endpoint.



 



    //



    // Endpoint
Descriptor



    //



    7,                               // The size of
the endpoint descriptor.



   
USB_DTYPE_ENDPOINT,             
// Descriptor type is an endpoint.



   
USB_EP_DESC_OUT | USB_EP_TO_INDEX(DATA_OUT_ENDPOINT),



   
USB_EP_ATTR_BULK,               
// Endpoint is a bulk endpoint.



   
USBShort(DATA_OUT_EP_MAX_SIZE), 
// The maximum packet size. 64bytes



    0,                               // The polling
interval for this endpoint.



};



 



关于USB Device的中断处理:参考 PDL-USBL-UG-3047.pdf



P139 “USB Event Handlers”

P144 “Interrupt Vector Selection”



 



typedef struct





         tCustomHandlers sCallbacks;



const unsigned char * pDeviceDescriptor;



const tConfigHeader
*const *ppConfigDescriptors;



const unsigned char *const *ppStringDescriptors;



unsigned long ulNumStringDescriptors;



const tFIFOConfig *psFIFOConfig;



tDeviceInfo



USB device 应用主要实现一些响应USB事件的callback函数。这些Callback函数通过USBDCDInit()函数调用的tDeviceInfo.sCallbacks传递给USB Device API



 



sCallbacks tCustomHandlers类型的数据结构。每个tCustomHandlers都包含一组USB event的函数指针。应用必须为每个关心的Event提供可用函数指针的表。对于不关心的event将对应的函数指针设置为NULL



typedef struct



{

         void (*pfnGetDescriptor)
(unsigned long ulIndex,



                          tUSBRequest
*pUSBRequest);



         tStdRequest pfnRequestHandler;



tInterfaceCallback pfnInterfaceChange;



tInfoCallback pfnConfigChange;



tInfoCallback pfnDataReceived;



tInfoCallback pfnDataSent;



tUSBIntHandler pfnResetHandler;



tUSBIntHandler pfnSuspendHandler;



tUSBIntHandler pfnResumeHandler;



tUSBIntHandler pfnDisconnectHandler;



tUSBEPIntHandler pfnEndpointHandler;



}tCustomHandlers



 



USB FIFO的配置  参考 PDL-USBL-UG-3047.pdf 
P143
USB
FIFO Configuration



USB 控制器FIFO 必须被合理的分配给各个端点。尽管实际的配置是通过USB Library完成的,应用程序也必须传递一个结构给USB Library以表示FIFO的配置情况。tFIFOConfig 结构包含两个数组,第一个数组表示3IN 端点的FIFO配置参数,第二个数组表示3OUT端点的FIFO配置参数。EP0使用固定的FIFO配置,不需要考虑。



typedef struct



{



         tFIFOEntry sIn[NUM_USB_EP-1];



tFIFOEntry sOut[NUM_USB_EP-1];



}tFIFOConfig



 



一个tFIFOConfig的指针通过tDeviceInfo结构中的psFIFOConfig传递给USBCDCInit()函数。



如果应用不希望使用DMA或双Buffer等特殊的Features,可以使用g_sUSBDefaultFIFOConfig来初始化FIFO



如果缺省的FIFO配置不能满足,就需要声明一个新的tFIFOConfig结构并用psFIFOConfig指向这个结构。



 



 



所有USB Device API的应用程序都必须将中断向量表中的硬件USB控制器的中断函数设置为USB0DeviceIntHandler



 



 



经过以上的一番折腾,我觉得自己对LM3S3748有了一定的了解。最近有个手持机的设计需求到了我手上,打开看看。



部分设计需求跟大家分享一下:



系统接口:



1.  
LCD
I/F
:可以驱动TFT LCD, OLED 128*64,  1.8,2.8, 3.2



2.  
USB:
Host x1
3G Modem



3.  
I2S
x1
用来接外部Audio CODEC. 用以支持录音和播放



4.  
Audio:
Mic x1, Lineout x1, Speaker out x1



5.  
SD
x1 : MicroSD



6.  
SPI
x2 :
一路接WiFi,一路接其他外设



7.  
马达驱动:水平马达,垂直马达



8.  
键盘:5*5键盘(一个独立的开机按键)



9.  
RTC
x1



10.I2C
x1:



11.Charger x1



12.Uart x2



 



电源管理:



1600mAh锂电池:3.8V电压。支持300mA充电(设计2小时充满),



 



2.       
RTC后备电池:3V,系统支持休眠唤醒模式,支持充电模式。(要注意休眠唤醒切换过程中软件的稳定性)。支持定时开机唤醒功能。



3.       
工作续航:6小时。待机续航1周。



 



再考虑整个系统的BOM成本和量产,开发工具的特点,我觉得比较有底了。决定用LM3S3748来做主控MCU。然后,就是常规的开发步骤:首先,从原理图开始。原理图进行到一半。我忽然觉得应该去Luminary的网站下载最新的资料看看,也许LuminaryTI收购后会有新的变化。下载新的EVB光盘后,仔细看过新Datasheet后,发现errata文件。



相关Errata文档下载



看完之后马上汗下,这款MCU还真是有不少Bug。其中有三条基本是做手持设备不能容忍的:



1. 
Hibernation Module管理有问题:VBATVDD先上电,系统会有1.6mA的漏电。



2. 
休眠唤醒不能Debug!这让人怎么调试这些状态呢。干跑程序?



3. 
一些PINESDHM 2KV都不能达到。



4. 
USB接口部分有些很奇怪的要求。懒得细琢磨他们的USB PHY了。



 



看完这个errata文档,我那个痛苦呀!辛苦半天评估的过程,基本泡汤了。我可不会冒险再继续调试它的电源管理部分了。



手持机项目还要继续我会选择另一款CortexM3MCU进行开发,请大家继续关注。



 



frm说:虽然,LM3S3748从目前的版本看,不太适合手持设备。但是,如果是对电源管理要求不高的系统到是可以尝试。它的特点就是USB应用比较容易上手。



另,我们今后一定要关注各类MCU的最新动态,errata是必看的。这都是原厂的开发人员辛苦调试的结果。也能使我们的开发少走弯路!



 





 



相关文档下载:

本文全文下载



EKK-LM3S3748 CD光盘下载



Luminary原理图库



LM3S3748 uC/OS-II的例程下载



我未完成的原理图下载,仅供大家参考!





 



PARTNER CONTENT

文章评论3条评论)

登录后参与讨论

用户243688 2009-11-10 17:35

只读存储器 (ROM) 中USB 库怎么得到?麻烦告诉一声

用户243688 2009-11-10 17:28

刚查到只读存储器 (ROM) 中进行预编程的 Stellaris Peripheral Driver Library,这个USB的ROM也有吧?呵呵

用户243688 2009-11-10 17:25

你好,我能看一下3748完整的USB 库,我想用它的HOST口做视频采集,谢谢啦 我的邮箱:zhengpeng06@163.com
相关推荐阅读
用户1316725 2010-11-18 08:35
轻松绑定工控主板的隐盾系列DOM电子盘
       经过2年多的研发,我公司正式推出隐盾系列DOM电子盘,并成功取得专利。隐盾系列DOM盘,除了支持从128MB~8G的容量外。它的最大特点是能够使DOM盘与工控主板1对1的绑定。目前,很多...
用户1316725 2010-07-01 07:39
《电子技术专业基础与实务》中级 复习资料
职称考试资料不好找呀,共享给大家!个人经验,多看晶体管部分和传感器原理部分,惠更斯电桥,JK/RS触发器,卡诺图等。希望大家都能顺利通过,看资料通过了的XDJM可要记得把本贴顶起来呀! 《电子技术专业...
用户1316725 2009-12-17 11:21
民间统计S3C2410/S3C2440出货情况 强贴大家顶起来吧。
p>今天在测试中发现,LPC2300的RTC时钟断电后,再重新加电,时间不走。网上有很多评论,也有类似的问题。不过,我把程序改了一下就可以了。程序如下(错误的程序):void RTC_Init(...
用户1316725 2009-12-14 09:09
SDIO卡初始化不过的调试笔记
前一段时间去了趟上海. 说是在客户平台上SDIO接口不正常,卡初始化不过.到了现场,先用示波器对各路电源和复位时序进行了检查.都没啥问题.然后,单步跟到发送SD CMD0(Reset)命令,发现卡的状...
用户1316725 2009-10-11 16:43
STM32上应用uCOSII学习笔记(2)
STM32上应用uCOSII学习笔记(2) 本文全文下载 2009.10.814611.pdf STM32F103xx用户手册学习STM32F103xx系列芯片能够做到Pin to Pin,软件和特性...
EE直播间
更多
我要评论
3
15
关闭 站长推荐上一条 /3 下一条