SPI驱动写法的问题

发表在 SPI2019-10-24 10:29 [复制链接] 1 82

本帖最后由 bevis 于 2019-10-24 10:31 编辑
- \% e# A& q: W6 p$ B' X7 ^4 m& |0 U  u7 r& n5 [
根据文档SPI读写方式有几种,在实际应用中使用rt_spi_send_then_recv更容易失败 ,使用 rt_spi_transfer_message反而更容易成功,文档说两者都是一样的关系。以下是我写的两套写法,自认为读写流程都是一样的。结果使用rt_spi_transfer_message成功,前者接口却是失败的。! v" {( l0 B" G4 c) ?  j
难道这两套流程不一样吗???函数名:1 v5 \: T$ w' @
  1. uint8_t spiTxRx(const uint8_t *txData, uint8_t *rxData, uint16_t length)
复制代码
% Z, g% d, s5 p% R1 o* ]3 G9 V& j
) y( x$ J$ w7 J; k; x- P7 ^
第一段使用rt_spi_send_then_recv   -- 执行结果失败, 我说的失败,不是SPI驱动失败,而是SPI设备读写初始化运行失败) s  V% x' D: C9 n" n2 x) h
  1. if((NULL == txData) && (NULL == rxData))
    3 J/ w; _+ w2 L& i$ w% r
  2.         {
    : n- x9 ]  z! J4 X2 y; f* _6 u% E4 y$ H
  3.             return i;8 |6 T$ c& i1 V- N8 o7 a
  4.         }
    2 H$ z. M  l' m3 T* r& q, c
  5.         
    ) r3 I- Z4 v6 T4 D0 {# |% @
  6.         if(length > 128)
    ( `% R' M: A2 I1 _& x4 U/ ^% c
  7.         {  T, b6 ^; M) V6 Q9 Q
  8.                         return i;
    % l0 @; d- ^* R: R/ E5 [5 j
  9.         }
    " j- C. Q  b2 r5 Q% {$ [- S; j
  10.         if(txData != NULL)
      v" @& ?4 {' N! _" v( z/ Y7 f! w
  11.         {
    3 m" S0 c* F4 E; q. d2 B; [
  12.                 memcpy(tx_buff, txData, length);( p1 \+ `. b: G9 v
  13.                 if(rxData != NULL)
    ! t% `5 d- _- Z+ K- A4 |! O' L& B( }
  14.                 {
    ( a; \) [1 H, d8 e
  15.                         rt_spi_send_then_recv(spi_dev_st25r, tx_buff, length, rx_buff, length);
    3 F- t8 X; S3 `/ K1 Y4 m  @
  16.                         memcpy(rxData, rx_buff, length);& i+ q3 F; f( Q. b( o  x
  17.                 }
    ! E; z3 t2 |6 h% G
  18.                 else // RX NULL, 输入缓冲不能为空9 f" l; r3 d/ O8 {* K4 n* ]
  19.                 {6 ~/ D' t+ \1 n- y6 ?" d+ v) x
  20.                         rt_spi_send_then_recv(spi_dev_st25r, txData, length, RT_NULL, 0);
    0 m" H3 m% C# A' F( F, f( {7 D
  21.                 }
    9 Y& a' A: t+ P  T# I' h
  22.         }
    ) z; `9 Y* f. h* \* @" o" P6 P+ u% v
  23.         else // TX NULL
    8 a" ]- h0 g4 L
  24.         {# J" l& n! S6 c1 j
  25.                 if(rxData != NULL)
    0 m; R! }! x  U
  26.                 {
    : \+ y1 Q: z' G2 I' H
  27.                         rt_spi_send_then_recv(spi_dev_st25r, RT_NULL, 0, rx_buff, length);
    " A3 s6 F9 ]: W- T2 d& f
  28.                         memcpy(rxData, rx_buff, length);
    2 A/ Z: b6 u0 C
  29.                 }
    3 G" E$ y7 R* `# U; {( A1 i& K
  30.         }) w* v8 u$ t' }8 A! ^$ k
  31.         rt_thread_mdelay(5);
    : G# q8 Z0 L7 E4 e- ?# C( ?. S
  32.   return i;
复制代码
( j, T! D# H& @: J* w( Q
. `" A1 A/ D2 W( V
第二段rt_spi_transfer_message -- 成功
- O/ J; z( s5 c/ i! |
  1. uint8_t i=0;
    / X( s/ T8 b; Z) c6 ?2 @) z$ U
  2.         if((NULL == txData) && (NULL == rxData))
    9 I- x& }5 s4 _# `4 ]: G6 c
  3.         {
    3 b( M7 {1 ~1 @" N  ^
  4.             return i;& g2 P0 V" F: T; ]& X: K
  5.         }. R, u  ~( C9 v4 o4 t
  6.         * u2 T$ Z) ]! g0 t& v* [/ y+ S
  7.         if(length > 128)
    - j9 ~1 A: n( e) f7 T/ y
  8.         {
    , Z1 G' ^( P$ j. ^
  9.                         return i;
    1 M" w. Q" Y6 i. c
  10.         }
    7 p* S. a8 ^" A
  11.         struct rt_spi_message msg1, msg2;
    ; t! ?" C- T5 U  A. b& h# q
  12.         if(txData != NULL)$ i$ a& Y( y7 m$ r2 ^. h
  13.         {2 r# F$ X( C+ S( M
  14.                 if(rxData != NULL) // RX 非空9 D0 G3 X! w$ @1 ^
  15.                 {$ @& B! H5 \. K# N* z) p7 |
  16.                         msg1.send_buf   = txData; // 发送缓存
    ( a' R4 \$ I% v( O' s$ k; W# B  e5 y
  17.                         msg1.recv_buf   = rx_buff;// 接收缓存
    9 q0 w! }' {8 ~) g0 K6 o
  18.                         msg1.length     = length;! [# w( F# d* e' ^6 A
  19.                         msg1.cs_take    = 1;
    - p# o  ?5 g+ v9 f) W7 `9 s: a9 I
  20.                         msg1.cs_release = 0;' M5 d0 k3 o3 Y
  21.                         msg1.next       = &msg2;
    7 k7 V5 D  ~3 L" m  c: I
  22. 1 k! F6 Q7 v! n( C0 P
  23.                         msg2.send_buf   = RT_NULL;; ~+ \6 o7 K' c" Y; F
  24.                         msg2.recv_buf   = RT_NULL; 3 E5 h' D( V/ @0 {
  25.                         msg2.length     = 0;% a* t4 p3 i) d' F! C
  26.                         msg2.cs_take    = 0;
    2 |0 B/ }# |6 L/ f0 H! c
  27.                         msg2.cs_release = 1;" D1 ?3 f+ t9 O, D! ~* U
  28.                         msg2.next       = RT_NULL;
    0 C# i' q6 Z- A6 H$ c" F
  29.                         rt_spi_transfer_message(spi_dev_st25r, &msg1);
    * `: H* n6 G" L% |' }
  30.                         memcpy(rxData, rx_buff, length);$ O* P( {0 G1 ?) ~
  31.                 }
    % z5 [) x! d# h9 d" s
  32.                 else // RX NULL
    & k/ e) O. p, a) y3 l; t- u6 q: q
  33.                 {
    6 P1 U5 \) o* Q8 r
  34.                         msg1.send_buf   = txData; // 发送缓存
    4 O/ y$ P- J- n8 e! M( B) P
  35.                         msg1.recv_buf   = RT_NULL;
      V& [$ Y7 a. H# v+ o
  36.                         msg1.length     = length; // 发送长度
    7 N8 y! x3 |( S" D
  37.                         msg1.cs_take    = 1;
    1 N& L' o- N- \4 b# i+ V6 t
  38.                         msg1.cs_release = 0;+ s; `/ S: A, c1 d% W6 ?
  39.                         msg1.next       = &msg2;* j. z: Z1 F) i8 U6 v* B: x

  40. ) G+ A5 W( I) S% l" [
  41.                         msg2.send_buf   = RT_NULL;
    ) u. A: Z# p( _) r4 Y
  42.                         msg2.recv_buf   = RT_NULL;+ E/ {: [# _8 F  p& `% N. Q
  43.                         msg2.length     = 0;
    ) a/ _  z- `! i5 J& |( L$ ~
  44.                         msg2.cs_take    = 0;
    & v) A$ z5 G; }) ?; I0 X
  45.                         msg2.cs_release = 1;
    7 I" b3 T3 E5 b. O
  46.                         msg2.next       = RT_NULL;
    0 |9 d) o4 C% N- `  m
  47.                         rt_spi_transfer_message(spi_dev_st25r, &msg1);# _& ~# r$ b( f/ A4 q# ^- c
  48.                 }
    1 P  d' p5 k7 V- n4 J; w" W
  49.         }# k, b! q' f( r# n6 k" k9 a0 z
  50.         else // TX NULL
    + g6 }$ {0 g2 N2 Z# F$ W/ P
  51.         {
    # M! o" A" z* L
  52.                 if(rxData != NULL) // RX 非空+ s# n2 n* P' e' h  H0 ^
  53.                 {( y0 U% X, N$ b/ |( y: u( D
  54.                         msg1.send_buf   = RT_NULL;' J# G) E4 E$ H( U) C& E' Z. N3 c
  55.                         msg1.recv_buf   = RT_NULL;
    2 U) Z% y2 c2 [6 P" B
  56.                         msg1.length     = 0;
    - y: B( @# S+ m; s& n( w
  57.                         msg1.cs_take    = 1;1 |4 [3 u, j/ [- k; W
  58.                         msg1.cs_release = 0;
    4 f1 q2 @3 V& y  @
  59.                         msg1.next       = &msg2;
      q% l1 H: M+ ?
  60. , D: E. [: ]5 n# j2 l7 a
  61.                         msg2.send_buf   = RT_NULL;+ G$ Z; X$ [- Y+ [' ~
  62.                         msg2.recv_buf   = rx_buff; // 接收缓存
    , C: o$ D5 n6 W" A. q. A/ W  t
  63.                         msg2.length     = length;
    " T" e0 v+ Q( Q. e+ K& v* V
  64.                         msg2.cs_take    = 0;- n& x9 j. e. |  e: V( q
  65.                         msg2.cs_release = 1;
    2 @- X9 b; i# u% A1 I
  66.                         msg2.next       = RT_NULL;
    ; n/ I5 A( B/ N& ?; @
  67.                         rt_spi_transfer_message(spi_dev_st25r, &msg1);
    / E: H8 U& C+ x  u+ Y
  68.                         memcpy(rxData, rx_buff, length);
    - A* F# T5 ?1 L( A4 g( S4 B7 q+ v
  69.                 }
    2 L. V! V& V  A9 N. o$ |3 G* j6 i7 R
  70.         }. `4 U, @" Y# i* F& j
  71.         rt_thread_mdelay(5);
    ; O2 v% A- y0 R1 ]: _
  72.   return i;
复制代码

. Q* c# u- G; ]& N4 V. L+ W
5 Y" i9 {1 h3 Z4 J6 c( W- d  L8 D3 j7 A) X% \4 O

6 _/ A3 U/ i. ?. t  w( `- M. z

- X( l) F' s0 [! Z* e
, Q8 R( [. x; s( a5 c' c# Z% v  R! e8 ?9 Z; x% b- l
/ G0 Y7 U& |' w# V
9 p# Z: r1 @9 U4 X7 O$ R! H: v0 }
使用道具 举报 显示全部楼层 回复
最新评论 | 正序浏览
显示全部楼层 |楼层直达:
发表于 2019-10-24 14:22:20 | 显示全部楼层
本帖最后由 aozima 于 2019-10-24 14:29 编辑
( c; c) n; f$ ~2 }7 S# D- E1 }% C3 H1 x( f6 [
逻辑分析仪解君愁。/ ^% Y6 ~5 n' \) Y
) \1 H" W6 J- V2 ]
另外,
$ K9 ~2 a2 _+ b' {只发不收是 rt_spi_send,
& E' l6 U: H8 e, i1 ]& ~只收不发是 rt_spi_recv.- X1 \* P" L# i5 [# X" {
先发再收是 rt_spi_send_then_recv
, [7 i8 R- f: p& O2 }4 g: N
; t* h" K9 e2 R+ o* t& D3 j5 s* [0 [7 m0 a5 @" Y
rt_spi_send_then_send 和 rt_spi_send 是一样的,但是方便使用,他们底层都是通过 rt_spi_transfer 和 msg 搭配来实现的。9 h) c; ~+ }  K1 |

8 s9 q8 ~3 u2 ]# J; n
使用道具 举报 回复
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|RT-Thread开发者社区 ( 沪ICP备13014002号-1

有害信息举报电话:021-31165890 手机:18930558079

© 2006-2019 上海睿赛德电子科技有限公司

Powered by RT-Thread

快速回复 返回顶部 返回列表