【学习探索】Hello:LaunchPad(从)--SPI--EK LM3S811(主)

[复制链接]
 楼主| yirongfu 发表于 2012-7-5 09:34 | 显示全部楼层 |阅读模式
本帖最后由 yirongfu 于 2012-7-5 09:41 编辑

    此前一直使用模拟的SPI接口或者主机模式的SPI接口,未尝试过从机SPI编程,近期学习了视频教程,想试试来个跨界握手:通过LaunchPad上的MSP430G2553的硬件SPIEK-LM3S811上的SSISPI模式)进行互联,简化起见,MSP430G2553作为从机,LM3S811作为主机。利用LM3S811的虚拟串口来间接检验双向通讯效果,通讯的思路是LM3S811发出若干字节数据,MSP430G2553接收到后原文回传,LM3S811接收到回传直接通过UART显示到PC端的串口调试助手上。当然也可以逆过来设计,我这么选择只是为了实验的方便,因为需要尝试的重点是SPI通讯,其他的如虚拟串口可以利用LM3S的库来快速实现。关键的难点还是接口时序的选择,比如时钟的极性、相位等。
*****************************************

硬件连接(从评估板的引出端子处飞线互连):
PC1+MSP430G2553                                 PC2+ LM3S811
GNDPin20------------------------------GND(外侧引出焊盘列,下同)
UCA0SOMIP1.1------------------------SSIRx
UCA0SIMOP1.2------------------------SSITx
UCA0CLK P1.4-------------------------SSICLK
UCA0STE P1.5-------------------------SSIFss(可省)
*****************************************

注:目前的MSP430G2553器件手册SLAS735F3页第一个器件引脚图上,第4脚描述有误,多了个字母P,变成PUCA0SIMO了。




   
    接下来的重点就是编程了,首先需要查阅官方的例程,当然没有现成的上述连接方式的例程,不过
MSP430G2553倒是有两个分别作为从机和主机的例程,主从双方均为MSP430单片机,LM3S811也有SPI主机模式的例程,但没找着对应的从机例程。参考例程作如下设计:


1. MSP430G2553采用三线SPI从机模式,上电复位进行必要的初始化后进入低功耗LPM4状态,接收数据和发送数据均在中断服务程序内执行。这也是近期的视频教程第八讲“串行通信模块”里,丁经理反复强调的430适合低功耗设计的要求,为低功耗设计而设计,它可从任意低功耗模式(LPM)实现自动时钟起动,具体来说就是即使在CPU和所有时钟禁能的LPM4模式下都可以正常通信,不过请注意,这针对的是SPI的时钟取自SMCLK且作为从机的操作,在需要的时候SMCLK被自动激活,比如接收和发送操作就可以激活,并保持到操作执行完毕,然后回到激活前的低功耗状态(详见用户手册说明)。而如果作为主机,它需要向外输送时钟的,所以就跟低功耗模式相矛盾了。为了便于调试观察,设置了一个数组用于存放从SPI收到的数据,接收到一个字节立即回传该字节,芯片大部分时间处于LPM4,另外,联调时先运行该从机。调试环境CCSv4.2.4


2. LM3S811采用FreescaleSPI主机模式,SPH=1SPO=0,速率取500kHz8-bit数据宽度。注意,LM3S811数据手册里提到,当工作模式为主机模式时,系统时钟至少是SSIClk的两倍;当工作模式为从机模式时,系统时钟至少是SSIClk12。程序采用查询方式发送和接收数据,发送5个字符Hello,全部发送完毕再进行接收查询,接收的数据直接送UART口,UART口采用例程中的配置115200 bps8-N-1。调试环境IAREmbedded Workbench for ARM 5.30 Kickstart


3. 两个MCU的用户手册所述及的SPI接口模式不太一样,MSP430G2553并不像LM3S811那样区分出三种定义的SPI接口,从具体的配置来看,MSP430G2553LM3S811Freescale接口模式更为接近,就是不知道LM3S811支持的TI的模式是不是430上的SPI模式?最终基本可行的接口时序形式如下:
MSP430G2553CKPL=0CKPH=0


LM3S811FreescaleSPO= 0SPH=1

其实我一开始分析时,觉得SPO=0SPH=0更配对,可惜不对。


实验内容及结果总结:


1. MSP430G2553作为从机,SPI的总线时钟CLK取决于主机,当然,也不能让MCU的系统时钟低于SPI时钟线频率。实验过上电默认的约1MHz DCO,修改为8MHz,修改为4.37.3MHzRSELx = 12, DCOx = 3, MODx = 0),均可。稳妥起见,个人觉得系统时钟和总线频率的选择参考上述LM3S811数据手册的建议为宜。


2. 试了MSP430G2553配置为3线制,LM3S811配置为TI SPI模式,MSP430G2553接收到的数据错误。


3. LM3S811Freescale SPI是4线制,试验了如下情况:
· 分别试了用与不用SSISTE引脚(软件配置LM3S811I/O口部分的PA3屏蔽),MSP430G2553也分别配置了3线制和4线制,效果一样,这个STE脚应该就是多主机的时候才有用(此时注意如果使用4线JTAG进行调试,MSP430G2xx3UCA0STETMS引脚是复用的,开发环境可以使用Release JTAG on Go或者Free Run来避免冲突)。
· 试了LM3S811SPO=0SPH=0模式,MSP430G2553接收的数据正确,但LM3S811收到的其回传数据与原发出数据不一样,不过基本都是固定的几个值。
· 试了LM3S811SPO=0SPH=1模式,MSP430G2553接收数据正确,但回送给LM3S811的数据不完全一致,这个不一致是说收到的字符是对的,但先后顺序不吻合,比如实验中LM3S811发送的是“Hello”,MSP430G2553接收到的也是“Hello”,并且收一个字符回传一个,LM3S811也是读出一个就往串口送一个,结果PC端的串口调试器上得到的是“oHell”,就是说顺序错了,还试过只送三个字节“mhz”,同样存在这种现象,变成“hzm”,DCO改为8MHz后,又变成“zmh”。目前只调试到这种程度,虽然不完全吻合,排序有错,但至少收到正确的数据了,下面是串口终端的截图。


· 至于为何数据错位,LM3S811FIFO接收机制既然先进先出,照理不应该错,而且从机MSP430G2553也是按正确的先后顺序回传的,我想只可能在主机端接收和读取时才会产生错误,感觉也不应该是查询方式存取FIFO的问题,否则先不说错位,就连数值的正确性都无法保证。至于问题到底出在哪里,还没找出来,有待继续研究调试,如果有朋友知道,望指点!
· 现在总算深刻体会到了SPI总线的弱点:没有指定的流控制,没有完善的应答机制确认是否接收到数据。曾经将MSP430G2553的回传屏蔽,结果LM3S811的接收还是照常执行,收到的数据当然都是空白的,也就是说,SPI并没有像I2C那样有停止位、起始位、确认位之类的,它仅是依靠时钟线来作为存取数据的基准,如果主从机的时序没有严格对应上,就很可能出错。也曾怀疑我上述失败实验中有些就是数据回传与LM3S811开始程序读取FIFO之间的时间间隔问题,可惜没有示波器,暂时无法去验证分析。对于这种双MCU的由程序控制的SPI主从通讯,特别是两种不同架构的MCU之间的通讯,关键之关键,应该还是时序的同步。


    这回调试费了好几天的业余时间,因为没有好的实验条件,比调试I2C和其它仅作Slave用途的SPI器件要费劲的多,而且熟悉CCS调试环境也花了点时间,好在多少有些成果,亲自验证了MSP430LM3S之间的SPI互联,虽然还有数据错位的问题,但至少数值对了,如果大家有碰到类似的实际应用,可以再进一步做调试。


后面附上两MCU的主代码供大家参考。
另外,因为本文既涉及MSP430又涉及Stellaris,所以放到《讨论》这个版块。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| yirongfu 发表于 2012-7-5 09:55 | 显示全部楼层
本帖最后由 yirongfu 于 2012-7-5 09:59 编辑

发帖系统真的有些问题,烦人,上帖最后一张图重复,部分字体颜色也编辑不成功,期待新版!

下面是MSP430G2553的源代码,环境CCSv4.2.4
参考例程:slac485a ——MSP430G2xx3Code Examples.zip(例程有些描述也不一定都正确)


  1. #include "msp430g2553.h"



  2. unsigned char temp[5];

  3. static unsigned char num;



  4. void main(void)

  5. {

  6.   WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer

  7.   

  8.   /*if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)                                    


  9. {  

  10.    
  11. while(1);                              
  12. // If calibration constants erased
  13. // do not load, trap CPU!!

  14.   }


  15. //8Mhz


  16.   BCSCTL1 = CALBC1_8MHZ;//0x0C;                    // Set range


  17.   DCOCTL = CALDCO_8MHZ;//0x60;                     // Set DCO step +
  18. modulation */

  19.   

  20.   P1SEL = BIT1 + BIT2 + BIT4;

  21.   P1SEL2 = BIT1 + BIT2 + BIT4;

  22.   UCA0CTL1 = UCSWRST;                       // **Put state machine in reset**




  23.   UCA0CTL0 |= UCMSB + UCSYNC + UCMODE_2;               // 3-pin, 8-bit SPI slave

  24. //官方例程此处注释有误,变成了master
  25.   UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**

  26.   IE2 |= UCA0RXIE;                          // Enable USCI0 RX interrupt

  27.   temp[0] = '-';

  28.   temp[1] = '-';

  29.   temp[2] = '-';

  30.   temp[3] = '-';

  31.   temp[4] = '-';

  32.   num = 0;



  33.   __bis_SR_register(LPM4_bits + GIE);       // Enter LPM4, enable interrupts

  34. }



  35. // Echo character

  36. #pragma vector=USCIAB0RX_VECTOR

  37. __interrupt void USCI0RX_ISR (void)

  38. {

  39.   temp[num] = UCA0RXBUF;

  40.   while (!(IFG2 & UCA0TXIFG));

  41.   UCA0TXBUF = temp[num];

  42.   num++;
  43.   

  44.   if(num == 5)
  45.      num = 0;

  46. }
 楼主| yirongfu 发表于 2012-7-5 10:02 | 显示全部楼层
这是LM3S811的主程序源代码,环境IAR Embedded Workbench forARM 5.30 Kickstart,调试之用,所以只设计了单次发送和接收:
参考例程:StellarisWare_for_EK-LM3S811


  1. //*****************************************************************************



  2. #include "inc/hw_memmap.h"

  3. #include "inc/hw_ssi.h"

  4. #include "inc/hw_types.h"

  5. #include "driverlib/ssi.h"

  6. #include "driverlib/gpio.h"

  7. #include "driverlib/sysctl.h"

  8. #include "driverlib/uart.h"

  9. #include "utils/uartstdio.h"



  10. //*****************************************************************************

  11. //

  12. //! \addtogroup ssi_examples_list

  13. //! <h1>SPI Master
  14. (spi_master)</h1>

  15. //!

  16. //! This example shows how to configure the
  17. SSI0 as SPI Master.  The code will

  18. //! send three characters on the master Tx
  19. then polls the receive FIFO until

  20. //! 3 characters are received on the master
  21. Rx.

  22. //!

  23. //! This example uses the following
  24. peripherals and I/O signals.  You must

  25. //! review these and change as needed for
  26. your own board:

  27. //! - SSI0 peripheral

  28. //! - GPIO Port
  29. A peripheral (for SSI0 pins)

  30. //! - SSI0CLK - PA2

  31. //! - SSI0Fss - PA3

  32. //! - SSI0Rx  - PA4

  33. //! - SSI0Tx  - PA5

  34. //!

  35. //! The following UART signals are
  36. configured only for displaying console

  37. //! messages for this example.  These are not required for operation of SSI0.

  38. //! - UART0 peripheral

  39. //! - GPIO Port
  40. A peripheral (for UART0 pins)

  41. //! - UART0RX - PA0

  42. //! - UART0TX - PA1

  43. //!

  44. //! This example uses the following
  45. interrupt handlers.  To use this example

  46. //! in your own application you must add
  47. these interrupt handlers to your

  48. //! vector table.

  49. //! - None.

  50. //!

  51. //

  52. //*****************************************************************************



  53. //*****************************************************************************

  54. //

  55. // Number of bytes to send and receive.

  56. //

  57. //*****************************************************************************

  58. #define NUM_SSI_DATA 5



  59. //*****************************************************************************

  60. //

  61. // This function sets up UART0 to be used
  62. for a console to display information

  63. // as the example is running.

  64. //

  65. //*****************************************************************************

  66. void

  67. InitConsole(void)

  68. {

  69.    
  70. //

  71.    
  72. // Enable GPIO port A which is used for UART0 pins.

  73.    
  74. // TODO: change this to whichever GPIO port you are using.

  75.    
  76. //

  77.    
  78. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);



  79.    
  80. //

  81.    
  82. // Configure the pin muxing for UART0 functions on port A0 and A1.

  83.    
  84. // This step is not necessary if your part does not support pin muxing.

  85.    
  86. // TODO: change this to select the port/pin you are using.

  87.    
  88. //

  89.    
  90. GPIOPinConfigure(GPIO_PA0_U0RX);

  91.    
  92. GPIOPinConfigure(GPIO_PA1_U0TX);



  93.    
  94. //

  95.    
  96. // Select the alternate (UART) function for these pins.

  97.    
  98. // TODO: change this to select the port/pin you are using.

  99.    
  100. //

  101.    
  102. GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);



  103.    
  104. //

  105.    
  106. // Initialize the UART for console I/O.

  107.    
  108. //

  109.     UARTStdioInit(0);

  110. }



  111. //*****************************************************************************

  112. //

  113. // Configure SSI0
  114. in master Freescale (SPI) mode.
  115. This example will send out

  116. // 3 bytes of data, then wait for 3 bytes
  117. of data to come in.  This will all be

  118. // done using the polling method.

  119. //

  120. //*****************************************************************************

  121. int

  122. main(void)

  123. {

  124.    
  125. unsigned long ulDataTx[NUM_SSI_DATA];

  126.    
  127. unsigned long ulDataRx[NUM_SSI_DATA];

  128.    
  129. unsigned long ulindex;



  130.     //

  131.    
  132. // Set the clocking to run directly from the external
  133. crystal/oscillator.

  134.    
  135. // TODO: The SYSCTL_XTAL_ value must be changed to match the value of
  136. the

  137.    
  138. // crystal on your board.

  139.    
  140. //

  141.    
  142. SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |

  143.                    SYSCTL_XTAL_6MHZ);



  144.    
  145. //

  146.    
  147. // Set up the serial console to use for displaying messages.  This is

  148.    
  149. // just for this example program and is not needed for SSI operation.

  150.    
  151. //

  152.    
  153. InitConsole();



  154.    
  155. //

  156.    
  157. // Display the setup on the console.

  158.    
  159. //

  160.    
  161. UARTprintf("SSI ->\n");

  162.    
  163. UARTprintf("  Mode:
  164. SPI\n");

  165.    
  166. UARTprintf("  Data:
  167. 8-bit\n\n");

  168.    

  169.    
  170. /*SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

  171.    
  172. GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_3);

  173.    
  174. GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3,0);

  175.    
  176. GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3,GPIO_PIN_3);

  177.    
  178. GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3,~0);

  179.    
  180. GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3,GPIO_PIN_3);

  181.    
  182. SysCtlPeripheralDisable(SYSCTL_PERIPH_GPIOA);*/

  183.    
  184. //

  185.    
  186. // The SSI0 peripheral must be enabled for use.

  187.    
  188. //

  189.    
  190. SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);



  191.    
  192. //

  193.    
  194. // For this example SSI0 is used with PortA[5:2].  The actual port and pins

  195.    
  196. // used may be different on your part, consult the data sheet for more

  197.    
  198. // information.  GPIO port A needs
  199. to be enabled so these pins can be used.

  200.    
  201. // TODO: change this to whichever GPIO port you are using.

  202.    
  203. //

  204.    
  205. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);



  206.    
  207. //

  208.    
  209. // Configure the pin muxing for SSI0 functions on port A2, A3, A4, and
  210. A5.

  211.    
  212. // This step is not necessary if your part does not support pin muxing.

  213.    
  214. // TODO: change this to select the port/pin you are using.

  215.    
  216. //

  217.    
  218. GPIOPinConfigure(GPIO_PA2_SSI0CLK);

  219.    
  220. GPIOPinConfigure(GPIO_PA3_SSI0FSS);

  221.    
  222. GPIOPinConfigure(GPIO_PA4_SSI0RX);

  223.    
  224. GPIOPinConfigure(GPIO_PA5_SSI0TX);



  225.    
  226. //

  227.    
  228. // Configure the GPIO settings for the SSI pins.  This function also gives

  229.    
  230. // control of these pins to the SSI hardware.  Consult the data sheet to

  231.    
  232. // see which functions are allocated per pin.

  233.    
  234. // The pins are assigned as follows:

  235.    
  236. //      PA5 - SSI0Tx

  237.    
  238. //      PA4 - SSI0Rx

  239.    
  240. //      PA3 - SSI0Fss

  241.    
  242. //      PA2 - SSI0CLK

  243.    
  244. // TODO: change this to select the port/pin you are using.

  245.    
  246. //

  247.    
  248. GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 |

  249.                    GPIO_PIN_2);

  250.    
  251. //GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_2);



  252.    
  253. //

  254.    
  255. // Configure and enable the SSI port for SPI master mode.  Use SSI0,

  256.    
  257. // system clock supply, idle clock level low and active low clock in

  258.    
  259. // freescale SPI mode, master mode, 1MHz SSI frequency, and 8-bit data.

  260.    
  261. // For SPI mode, you can set the polarity of the SSI clock when the SSI

  262.    
  263. // unit is idle.  You can also
  264. configure what clock edge you want to

  265.    
  266. // capture data on.  Please
  267. reference the datasheet for more information on

  268.    
  269. // the different SPI modes.

  270.    
  271. //

  272.    
  273. //SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_TI,

  274.    
  275. //                  
  276. SSI_MODE_MASTER, 500000, 8);

  277.    
  278. SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_1,

  279.                        SSI_MODE_MASTER, 500000,
  280. 8);



  281.    
  282. //

  283.    
  284. // Enable the SSI0 module.

  285.    
  286. //

  287.    
  288. SSIEnable(SSI0_BASE);



  289.    
  290. //

  291.    
  292. // Read any residual data from the SSI port.  This makes sure the receive

  293.    
  294. // FIFOs are empty, so we don't read any unwanted junk.  This is done here

  295.    
  296. // because the SPI SSI mode is full-duplex, which allows you to send and

  297.    
  298. // receive at the same time.  The
  299. SSIDataGetNonBlocking function returns

  300.    
  301. // "true" when data was returned, and "false" when
  302. no data was returned.

  303.    
  304. // The "non-blocking" function checks if there is any data in
  305. the receive

  306.    
  307. // FIFO and does not "hang" if there isn't.

  308.    
  309. //

  310.    
  311. while(SSIDataGetNonBlocking(SSI0_BASE, &ulDataRx[0]))

  312.     {

  313.     }



  314.    
  315. //

  316.    
  317. // Initialize the data to send.

  318.    
  319. //

  320.    
  321. ulDataTx[0] = 'H';//s

  322.    
  323. ulDataTx[1] = 'e';//p

  324.    
  325. ulDataTx[2] = 'l';//i

  326.    
  327. ulDataTx[3] = 'l';//i

  328.    
  329. ulDataTx[4] = 'o';//i



  330.    
  331. //

  332.    
  333. // Display indication that the SSI is transmitting data.

  334.    
  335. //

  336.    
  337. UARTprintf("Sent:\n  ");



  338.    
  339. //

  340.    
  341. // Send 3 bytes of data.

  342.    
  343. //

  344.    

  345.    
  346. //SSIDataPut(SSI0_BASE, 'A');

  347.    

  348.    
  349. for(ulindex = 0; ulindex < NUM_SSI_DATA; ulindex++)

  350.     {

  351.       
  352. //

  353.       
  354. // Display the data that SSI is transferring.

  355.       
  356. //

  357.       
  358. UARTprintf("'%c' ", ulDataTx[ulindex]);



  359.       
  360. //

  361.       
  362. // Send the data using the "blocking" put function.  This function

  363.       
  364. // will wait until there is room in the send FIFO before returning.

  365.       
  366. // This allows you to assure that all the data you send makes it into

  367.       
  368. // the send FIFO.

  369.       
  370. //

  371.       
  372. SSIDataPut(SSI0_BASE, ulDataTx[ulindex]);

  373.     }



  374.    
  375. //

  376.    
  377. // Wait until SSI0 is done transferring all the data in the transmit
  378. FIFO.

  379.    
  380. //

  381.    
  382. while(!SSIBusy(SSI0_BASE))

  383.     {

  384.     }



  385.    
  386. //

  387.    
  388. // Display indication that the SSI is receiving data.

  389.    
  390. //

  391.    
  392. UARTprintf("\nReceived:\n
  393. ");



  394.    
  395. //

  396.    
  397. // Receive 3 bytes of data.

  398.    
  399. //

  400.    
  401. for(ulindex = 0; ulindex < NUM_SSI_DATA; ulindex++)

  402.     {

  403.       
  404. //

  405.       
  406. // Receive the data using the "blocking" Get function. This
  407. function

  408.       
  409. // will wait until there is data in the receive FIFO before returning.

  410.       
  411. //

  412.       
  413. SSIDataGet(SSI0_BASE, &ulDataRx[ulindex]);



  414.       
  415. //

  416.       
  417. // Since we are using 8-bit data, mask off the MSB.

  418.       
  419. //

  420.       
  421. ulDataRx[ulindex] &= 0x00FF;



  422.       
  423. //

  424.       
  425. // Display the data that SSI0 received.

  426.       
  427. //

  428.       
  429. UARTprintf("'%c' ", ulDataRx[ulindex]);

  430.     }

  431.    
  432. UARTprintf("\n");



  433.    
  434. while(1);

  435.    
  436. //

  437.    
  438. // Return no errors

  439.    
  440. //

  441.    
  442. //return(0);

  443. }
nwx8899 发表于 2012-7-5 12:00 | 显示全部楼层
mark 顶
 楼主| yirongfu 发表于 2012-7-6 23:50 | 显示全部楼层
谢谢捧场:)

没人解答我的问题吗?:L
mdq123 发表于 2012-7-26 19:59 | 显示全部楼层
xiexielouzhu
mdq123 发表于 2012-7-26 20:00 | 显示全部楼层
xiexielouzhu
wugang1213 发表于 2012-8-11 12:07 | 显示全部楼层
好东西 顶一顶
wangzhisunshine 发表于 2014-8-9 20:43 | 显示全部楼层
现在才看到这好东西,大赞!
wangzhisunshine 发表于 2014-8-9 20:45 | 显示全部楼层
还希望楼主持续更新。
u880 发表于 2014-8-11 08:16 | 显示全部楼层
好给力的分享啊
huigoushang 发表于 2014-8-11 08:18 | 显示全部楼层
受益匪浅 多谢分享
G21372 发表于 2014-8-11 08:21 | 显示全部楼层
楼主的分享真心不错
yangguangaisha 发表于 2014-8-11 08:24 | 显示全部楼层
楼主强悍 多谢分享
gexingyouxian 发表于 2014-8-11 08:26 | 显示全部楼层
简直不能更详细了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:生活将我们磨圆,是为了让我们滚得更远。。。 我来到这个世上就没打算活着回去!

99

主题

918

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部