@@ -48,14 +48,19 @@ int hm2_pktuart_parse_md(hostmot2_t *hm2, int md_index)
4848 //The PktUART declares a TX and RX module separately
4949 //And Rx can currently be v1 or v2
5050 if (md -> gtag == HM2_GTAG_PKTUART_TX
51- && !hm2_md_is_consistent_or_complain (hm2 ,md_index , 0 , 4 , 4 , 0x000F )) {
52- HM2_ERR ("inconsistent Module Descriptor!\n" );
51+ && !hm2_md_is_consistent (hm2 ,md_index , 0 , 4 , 4 , 0x000F )
52+ && !hm2_md_is_consistent (hm2 ,md_index , 1 , 4 , 4 , 0x000F )
53+ && !hm2_md_is_consistent (hm2 ,md_index , 2 , 4 , 4 , 0x000F )) {
54+ HM2_ERR ("Unsupported or inconsistent PktUART TX module (version %i)"
55+ "not loading driver \n" , md -> version );
5356 return - EINVAL ;
5457 }
5558 if (md -> gtag == HM2_GTAG_PKTUART_RX
56- && !hm2_md_is_consistent_or_complain (hm2 , md_index , 0 , 4 , 4 , 0x000F )
57- && !hm2_md_is_consistent_or_complain (hm2 , md_index , 1 , 4 , 4 , 0x000F )) {
58- HM2_ERR ("inconsistent Module Descriptor!\n" );
59+ && !hm2_md_is_consistent (hm2 , md_index , 0 , 4 , 4 , 0x000F )
60+ && !hm2_md_is_consistent (hm2 , md_index , 1 , 4 , 4 , 0x000F )
61+ && !hm2_md_is_consistent (hm2 , md_index , 2 , 4 , 4 , 0x000F )) {
62+ HM2_ERR ("Unsupported or inconsistent PktUART RX module (version %i)"
63+ "not loading driver \n" , md -> version );
5964 return - EINVAL ;
6065 }
6166
@@ -167,6 +172,157 @@ int hm2_pktuart_parse_md(hostmot2_t *hm2, int md_index)
167172 return r ;
168173}
169174
175+ EXPORT_SYMBOL_GPL (hm2_pktuart_setup_rx );
176+ int hm2_pktuart_setup_rx (char * name , unsigned int bitrate , unsigned int filter_hz , unsigned int parity , int frame_delay , bool rx_enable , bool rx_mask ){
177+ hostmot2_t * hm2 ;
178+ hm2_pktuart_instance_t * inst = 0 ;
179+ rtapi_u32 buff1 , buff2 ;
180+ int i ;
181+ int r = 0 ;
182+ rtapi_u32 filter ;
183+
184+ i = hm2_get_pktuart (& hm2 , name );
185+ if (i < 0 ){
186+ HM2_ERR_NO_LL ("Can not find PktUART instance %s.\n" , name );
187+ return - EINVAL ;
188+ }
189+
190+ inst = & hm2 -> pktuart .instance [i ];
191+
192+ /*
193+ PktUART V2+ RX regmap
194+ Bit 30 BadPop Error (read data FIFO with no data) RO
195+ Bits 29..22 RX data digital filter bits (7..0) (in ClockLow periods)
196+ Should be set to 1/2 bit time
197+ (or max=65535 if it cannot be set long enough)
198+ Bit 21 FrameBuffer has data RO
199+ Bits 20..16 Frames received RO
200+ Bit 17 Parity enable WO
201+ Bit 18 Odd Parity WO (1=odd, 0=even)
202+ Bits 15..8 InterFrame delay in bit times RW
203+ Bit 7 RXBusy (serial state machine busy)
204+ Bit 6 RXMask RO
205+ Bit 5 Parity Error RW
206+ Bit 4 RCFIFO Error RW
207+ Bit 3 RXEnable (must be set to receive packets) RW
208+ Bit 2 RXMask Enable (enables input data masking when transmitting) RW
209+ Bit 1 Overrun error (no stop bit when expected) (sticky) RW
210+ Bit 0 False Start bit error (sticky) RW*/
211+
212+ filter = inst -> clock_freq / filter_hz ;
213+ if (hm2 -> pktuart .rx_version >= 2 ){
214+ if (filter > 0xFFFF ) filter = 0xFFFF ;
215+ buff1 = (rtapi_u32 )((bitrate * 16777216.0 )/inst -> clock_freq ); //24 bits in v2+
216+ buff1 |= (rtapi_u32 )((filter & 0xFF00 ) << 16 );
217+ } else {
218+ if (filter > 0xFF ) filter = 0xFF ;
219+ buff1 = (rtapi_u32 )((bitrate * 1048576.0 )/inst -> clock_freq ); //20 bits in v0 & v1
220+ }
221+ buff2 = (rtapi_u32 )((filter & 0xFF ) << 22 );
222+ buff2 |= (rtapi_u32 )(rx_mask << 2 );
223+ buff2 |= (rtapi_u32 )(rx_enable << 3 );
224+ buff2 |= (rtapi_u32 )((frame_delay & 0xFF ) << 8 );
225+ if (parity > 0 ) buff2 |= 0x20000 ;
226+ if (parity == 1 ) buff2 |= 0x40000 ;
227+
228+ if (buff1 != inst -> rx_bitrate ){
229+ inst -> rx_bitrate = buff1 ;
230+ r += hm2 -> llio -> write (hm2 -> llio , inst -> rx_bitrate_addr , & buff1 , sizeof (rtapi_u32 ));
231+ }
232+ if (buff2 != inst -> rx_mode ){
233+ inst -> rx_mode = buff2 ;
234+ r += hm2 -> llio -> write (hm2 -> llio , inst -> rx_mode_addr , & buff2 , sizeof (rtapi_u32 ));
235+ }
236+
237+ if (r < 0 ) {
238+ HM2_ERR ("PktUART: hm2->llio->write failure %s setting up RX\n" , name );
239+ return -1 ;
240+ }
241+
242+ return 0 ;
243+ }
244+
245+ EXPORT_SYMBOL_GPL (hm2_pktuart_setup_tx );
246+ int hm2_pktuart_setup_tx (char * name , unsigned int bitrate , unsigned int parity , int frame_delay , bool drive_enable , bool drive_auto , int enable_delay ){
247+ hostmot2_t * hm2 ;
248+ hm2_pktuart_instance_t * inst = 0 ;
249+ rtapi_u32 buff1 , buff2 ;
250+ int i ;
251+ int r = 0 ;
252+
253+ i = hm2_get_pktuart (& hm2 , name );
254+ if (i < 0 ){
255+ HM2_ERR_NO_LL ("Can not find PktUART instance %s.\n" , name );
256+ return - EINVAL ;
257+ }
258+ inst = & hm2 -> pktuart .instance [i ];
259+
260+ /*
261+ PktUART V2+ TX regmap
262+ Bit 21 FrameBuffer Has Data RO
263+ Bits 20..16 Frames to send RO
264+ Bit 17 Parity enable WO
265+ Bit 18 Odd Parity WO (1=odd, 0=even)
266+ Bits 15..8 InterFrame delay in bit times RW
267+ Bit 7 Send busy RO
268+ Bit 6 Drive Enable bit (enables external RS-422/485 Driver when set) RW
269+ Bit 5 Drive enable Auto (Automatic external drive enable) RW
270+ Drive Enable Auto has priority over Drive Enable (bit 6 is a no-op if bit 5 is set)
271+ Bit 4 SCFIFO Error RO
272+ Bits 3..0 Drive enable delay (delay from asserting drive enable
273+ to start of data transmit. In CLock Low periods RW
274+ Drive enable delay is important to avoid start bit timing errors
275+ at high baud rates in RS-485 (half duplex) modes
276+ */
277+
278+ if (hm2 -> pktuart .tx_version >= 2 ){
279+ buff1 = (rtapi_u32 )((bitrate * 16777216.0 )/inst -> clock_freq ); //24 bits in v2+
280+ } else {
281+ buff1 = (rtapi_u32 )((bitrate * 1048576.0 )/inst -> clock_freq ); //20 bits in v0 & v1
282+ }
283+
284+ buff2 = (rtapi_u32 )(enable_delay & 0x0F );
285+ if (drive_auto ) buff2 |= 0x00020 ;
286+ if (drive_enable ) buff2 |= 0x00040 ;
287+ if (parity > 0 ) buff2 |= 0x20000 ;
288+ if (parity == 1 ) buff2 |= 0x40000 ;
289+ buff2 |= (rtapi_u32 )((frame_delay & 0xFF ) << 8 );
290+
291+ if (buff1 != inst -> tx_bitrate ){
292+ inst -> tx_bitrate = buff1 ;
293+ r += hm2 -> llio -> write (hm2 -> llio , inst -> tx_bitrate_addr , & buff1 , sizeof (rtapi_u32 ));
294+ }
295+ if (buff2 != inst -> tx_mode ){
296+ inst -> tx_mode = buff2 ;
297+ r += hm2 -> llio -> write (hm2 -> llio , inst -> tx_mode_addr , & buff2 , sizeof (rtapi_u32 ));
298+ }
299+
300+ if (r < 0 ) {
301+ HM2_ERR ("PktUART: hm2->llio->write failure %s setting up TX\n" , name );
302+ return -1 ;
303+ }
304+
305+ return 0 ;
306+ }
307+
308+ EXPORT_SYMBOL_GPL (hm2_pktuart_reset );
309+ void hm2_pktuart_reset (char * name ){
310+ hostmot2_t * hm2 ;
311+ hm2_pktuart_instance_t * inst = 0 ;
312+ rtapi_u32 buff ;
313+ int i ;
314+ i = hm2_get_pktuart (& hm2 , name );
315+ if (i < 0 ){
316+ HM2_ERR_NO_LL ("Can not find PktUART instance %s.\n" , name );
317+ return ;
318+ }
319+ inst = & hm2 -> pktuart .instance [i ];
320+ buff = 0x80010000 ;
321+ hm2 -> llio -> write (hm2 -> llio , inst -> tx_mode_addr , & buff , sizeof (rtapi_u32 )); // clear sends, data FIFO and count register
322+ hm2 -> llio -> write (hm2 -> llio , inst -> rx_mode_addr , & buff , sizeof (rtapi_u32 )); // clear receives, data FIFO and count register
323+ }
324+
325+
170326EXPORT_SYMBOL_GPL (hm2_pktuart_setup );
171327// use -1 for bitrate, tx_mode and rx_mode to leave the mode unchanged
172328// use 1 for txclear or rxclear to issue a clear command for Tx or Rx registers
@@ -185,12 +341,24 @@ int hm2_pktuart_setup(char *name, unsigned int bitrate, rtapi_s32 tx_mode, rtapi
185341 inst = & hm2 -> pktuart .instance [i ];
186342
187343 if (bitrate > 0 ){
188- buff = (rtapi_u32 )((bitrate * 1048576.0 )/inst -> clock_freq ); //20 bits in this version
189- if (buff != inst -> bitrate ){
190- inst -> bitrate = buff ;
191- r += hm2 -> llio -> write (hm2 -> llio , inst -> rx_bitrate_addr , & buff , sizeof (rtapi_u32 ));
344+ if (hm2 -> pktuart .tx_version >= 2 ){
345+ buff = (rtapi_u32 )((bitrate * 16777216.0 )/inst -> clock_freq ); //24 bits in v2+
346+ } else {
347+ buff = (rtapi_u32 )((bitrate * 1048576.0 )/inst -> clock_freq ); //20 bits in v0 & v1
348+ }
349+ if (buff != inst -> tx_bitrate ){
350+ inst -> tx_bitrate = buff ;
192351 r += hm2 -> llio -> write (hm2 -> llio , inst -> tx_bitrate_addr , & buff , sizeof (rtapi_u32 ));
193352 }
353+ if (hm2 -> pktuart .rx_version >= 2 ){
354+ buff = (rtapi_u32 )((bitrate * 16777216.0 )/inst -> clock_freq ); //24 bits in v2+
355+ } else {
356+ buff = (rtapi_u32 )((bitrate * 1048576.0 )/inst -> clock_freq ); //20 bits in v0 & v1
357+ }
358+ if (buff != inst -> rx_bitrate ){
359+ inst -> rx_bitrate = buff ;
360+ r += hm2 -> llio -> write (hm2 -> llio , inst -> rx_bitrate_addr , & buff , sizeof (rtapi_u32 ));
361+ }
194362 }
195363
196364 /* http://freeby.mesanet.com/regmap
@@ -280,7 +448,7 @@ int hm2_pktuart_send(char *name, unsigned char data[], rtapi_u8 *num_frames, rt
280448 HM2_ERR_NO_LL ("Can not find PktUART instance %s.\n" , name );
281449 return - EINVAL ;
282450 }
283- if (hm2 -> pktuart .instance [inst ].bitrate == 0 ){
451+ if (hm2 -> pktuart .instance [inst ].tx_bitrate == 0 ){
284452 HM2_ERR ("%s has not been configured.\n" , name );
285453 return - EINVAL ;
286454 }
@@ -403,7 +571,7 @@ int hm2_pktuart_read(char *name, unsigned char data[], rtapi_u8 *num_frames, rta
403571 * num_frames = 0 ;
404572 return - EINVAL ;
405573 }
406- if (hm2 -> pktuart .instance [inst ].bitrate == 0 ) {
574+ if (hm2 -> pktuart .instance [inst ].rx_bitrate == 0 ) {
407575 HM2_ERR ("%s has not been configured.\n" , name );
408576 * num_frames = 0 ;
409577 return - EINVAL ;
@@ -573,7 +741,7 @@ int hm2_pktuart_queue_get_frame_sizes(char *name, rtapi_u32 fsizes[]){
573741 return - EINVAL ;
574742 }
575743
576- if (hm2 -> pktuart .instance [inst ].bitrate == 0 ) {
744+ if (hm2 -> pktuart .instance [inst ].rx_bitrate == 0 ) {
577745 HM2_ERR ("%s has not been configured.\n" , name );
578746 return - EINVAL ;
579747 }
@@ -612,7 +780,7 @@ int hm2_pktuart_queue_read_data(char *name, rtapi_u32 data[], int bytes) {
612780 HM2_ERR_NO_LL ("Can not find PktUART instance %s.\n" , name );
613781 return - EINVAL ;
614782 }
615- if (hm2 -> pktuart .instance [inst ].bitrate == 0 ) {
783+ if (hm2 -> pktuart .instance [inst ].rx_bitrate == 0 ) {
616784 HM2_ERR ("%s has not been configured.\n" , name );
617785 return - EINVAL ;
618786 }
0 commit comments