123

Dependencies:   mbed

Fork of LG by igor Apu

Committer:
Kovalev_D
Date:
Wed Feb 03 10:44:42 2016 +0300
Revision:
22:12e6183f04d4
[thyz

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Kovalev_D 22:12e6183f04d4 1
Kovalev_D 22:12e6183f04d4 2 /**--------------File Info---------------------------------------------------------------------------------
Kovalev_D 22:12e6183f04d4 3 ** File name: el_lin.c
Kovalev_D 22:12e6183f04d4 4 ** Last modified Date: 2011-08-22
Kovalev_D 22:12e6183f04d4 5 ** Last Version: V1.00
Kovalev_D 22:12e6183f04d4 6 **--------------------------------------------------------------------------------------------------------
Kovalev_D 22:12e6183f04d4 7 ** Created by: Electrooptica Incor.
Kovalev_D 22:12e6183f04d4 8 ** Created date: 2011-08-22
Kovalev_D 22:12e6183f04d4 9 ** Version: V1.00
Kovalev_D 22:12e6183f04d4 10 **--------------------------------------------------------------------------------------------------------
Kovalev_D 22:12e6183f04d4 11 *********************************************************************************************************/
Kovalev_D 22:12e6183f04d4 12 #include "CyclesSync.h"
Kovalev_D 22:12e6183f04d4 13 #include "CntrlGLD.h"
Kovalev_D 22:12e6183f04d4 14 #include "el_lin.h"
Kovalev_D 22:12e6183f04d4 15
Kovalev_D 22:12e6183f04d4 16 #define UART1TEST
Kovalev_D 22:12e6183f04d4 17 #define UART1REC
Kovalev_D 22:12e6183f04d4 18 /*
Kovalev_D 22:12e6183f04d4 19 struct {
Kovalev_D 22:12e6183f04d4 20 uint32_t rcv_num_byt;
Kovalev_D 22:12e6183f04d4 21 uint32_t rcv_num_byt_old;
Kovalev_D 22:12e6183f04d4 22 uint32_t rcv_Rdy;
Kovalev_D 22:12e6183f04d4 23 char rcv_copy[64];
Kovalev_D 22:12e6183f04d4 24 char rcv_buf[64];
Kovalev_D 22:12e6183f04d4 25 int32_t rx_buf_copy;
Kovalev_D 22:12e6183f04d4 26 int32_t rcv_byt_copy;
Kovalev_D 22:12e6183f04d4 27 }RECIEVER;
Kovalev_D 22:12e6183f04d4 28
Kovalev_D 22:12e6183f04d4 29 struct {
Kovalev_D 22:12e6183f04d4 30 uint32_t trm_num_byt;
Kovalev_D 22:12e6183f04d4 31 uint32_t trm_rate;
Kovalev_D 22:12e6183f04d4 32 uint32_t trm_cycl;
Kovalev_D 22:12e6183f04d4 33 uint32_t num_of_par;
Kovalev_D 22:12e6183f04d4 34 char trm_buf[64];
Kovalev_D 22:12e6183f04d4 35 void* addr_param[16];
Kovalev_D 22:12e6183f04d4 36 uint32_t size_param[16];
Kovalev_D 22:12e6183f04d4 37 uint32_t trm_ena;
Kovalev_D 22:12e6183f04d4 38 }TRANSMITTER;
Kovalev_D 22:12e6183f04d4 39 */
Kovalev_D 22:12e6183f04d4 40 uint32_t rcv_num_byt;
Kovalev_D 22:12e6183f04d4 41 uint32_t rcv_num_byt_old;
Kovalev_D 22:12e6183f04d4 42 uint32_t rcv_Rdy;
Kovalev_D 22:12e6183f04d4 43 char rcv_copy[64];
Kovalev_D 22:12e6183f04d4 44 char rcv_buf[64];
Kovalev_D 22:12e6183f04d4 45 int32_t rx_buf_copy;
Kovalev_D 22:12e6183f04d4 46 int32_t rcv_byt_copy;
Kovalev_D 22:12e6183f04d4 47
Kovalev_D 22:12e6183f04d4 48 uint32_t trm_num_byt;
Kovalev_D 22:12e6183f04d4 49 uint32_t trm_rate;
Kovalev_D 22:12e6183f04d4 50 uint32_t num_of_par;
Kovalev_D 22:12e6183f04d4 51 char trm_buf[64];
Kovalev_D 22:12e6183f04d4 52 void* addr_param[16];
Kovalev_D 22:12e6183f04d4 53 uint32_t size_param[16];
Kovalev_D 22:12e6183f04d4 54 uint32_t trm_ena;
Kovalev_D 22:12e6183f04d4 55
Kovalev_D 22:12e6183f04d4 56 uint32_t line_err;
Kovalev_D 22:12e6183f04d4 57 uint32_t line_sts;
Kovalev_D 22:12e6183f04d4 58
Kovalev_D 22:12e6183f04d4 59 uint32_t EnablLength = 12;
Kovalev_D 22:12e6183f04d4 60 uint32_t LLI0_TypeDef[4];
Kovalev_D 22:12e6183f04d4 61 uint32_t LLI1_TypeDef[4];
Kovalev_D 22:12e6183f04d4 62 uint32_t EnablTx = 0x80;
Kovalev_D 22:12e6183f04d4 63 uint32_t EnablDMA = 0;
Kovalev_D 22:12e6183f04d4 64 /******************************************************************************
Kovalev_D 22:12e6183f04d4 65 ** Function name: DMA_IRQHandler
Kovalev_D 22:12e6183f04d4 66 **
Kovalev_D 22:12e6183f04d4 67 ** Descriptions: DMA interrupt handler
Kovalev_D 22:12e6183f04d4 68 **
Kovalev_D 22:12e6183f04d4 69 ** parameters: None
Kovalev_D 22:12e6183f04d4 70 ** Returned value: None
Kovalev_D 22:12e6183f04d4 71 **
Kovalev_D 22:12e6183f04d4 72 ******************************************************************************/
Kovalev_D 22:12e6183f04d4 73 int check_lcc(void) //e. CRC checking //r.ïðîâåðêà êîíòðîëüíîé ñóììû
Kovalev_D 22:12e6183f04d4 74 {
Kovalev_D 22:12e6183f04d4 75 int iCRC_calc, CRC_calc = 0, CRC_real;
Kovalev_D 22:12e6183f04d4 76
Kovalev_D 22:12e6183f04d4 77 for (iCRC_calc = 1; iCRC_calc < (rcv_num_byt-2); iCRC_calc++)
Kovalev_D 22:12e6183f04d4 78 CRC_calc += rcv_buf[iCRC_calc];
Kovalev_D 22:12e6183f04d4 79
Kovalev_D 22:12e6183f04d4 80 CRC_real = (rcv_buf[rcv_num_byt-2] << 8) | rcv_buf[rcv_num_byt-1];
Kovalev_D 22:12e6183f04d4 81
Kovalev_D 22:12e6183f04d4 82 return (CRC_real - CRC_calc);
Kovalev_D 22:12e6183f04d4 83 }
Kovalev_D 22:12e6183f04d4 84 void PacketSafing(void)
Kovalev_D 22:12e6183f04d4 85 {
Kovalev_D 22:12e6183f04d4 86 /* int j; static char rcv_buf_copy[16];
Kovalev_D 22:12e6183f04d4 87 for (j=2; j<rcv_num_byt; j++)
Kovalev_D 22:12e6183f04d4 88 {
Kovalev_D 22:12e6183f04d4 89 if (rcv_buf[j] == 0xCC);
Kovalev_D 22:12e6183f04d4 90 rcv_buf_copy[0] = 0xCC;
Kovalev_D 22:12e6183f04d4 91 // if ((rcv_buf[j] < 3) || (rcv_buf[j] == 0x1F))
Kovalev_D 22:12e6183f04d4 92 } */
Kovalev_D 22:12e6183f04d4 93 }
Kovalev_D 22:12e6183f04d4 94
Kovalev_D 22:12e6183f04d4 95 /******************************************************************************
Kovalev_D 22:12e6183f04d4 96 ** Function name: Line_1_Rcv
Kovalev_D 22:12e6183f04d4 97 **
Kovalev_D 22:12e6183f04d4 98 ** Descriptions: receive process preparation
Kovalev_D 22:12e6183f04d4 99 **
Kovalev_D 22:12e6183f04d4 100 ** parameters: None
Kovalev_D 22:12e6183f04d4 101 ** Returned value: None
Kovalev_D 22:12e6183f04d4 102 **
Kovalev_D 22:12e6183f04d4 103 ******************************************************************************/
Kovalev_D 22:12e6183f04d4 104 void Line_1_Rcv(void)
Kovalev_D 22:12e6183f04d4 105 {
Kovalev_D 22:12e6183f04d4 106 static int ToWaitEnd, ErrReg ;
Kovalev_D 22:12e6183f04d4 107
Kovalev_D 22:12e6183f04d4 108
Kovalev_D 22:12e6183f04d4 109
Kovalev_D 22:12e6183f04d4 110
Kovalev_D 22:12e6183f04d4 111 while ((LPC_UART1->LSR & RecievBufEmpty) != 0) //e. reciever contain some information
Kovalev_D 22:12e6183f04d4 112 rcv_buf[rcv_num_byt++] = LPC_UART1->RBR;//÷òåíèå èíôîðìàöèè èç áóôåðà.
Kovalev_D 22:12e6183f04d4 113
Kovalev_D 22:12e6183f04d4 114
Kovalev_D 22:12e6183f04d4 115
Kovalev_D 22:12e6183f04d4 116
Kovalev_D 22:12e6183f04d4 117 if (( ToWaitEnd > 25000)) //e. end part of packet is absent //r. íå äîæäàëèñü êîíöà ïàêåòà
Kovalev_D 22:12e6183f04d4 118 {
Kovalev_D 22:12e6183f04d4 119 do
Kovalev_D 22:12e6183f04d4 120 rcv_buf[--rcv_num_byt] = 0;
Kovalev_D 22:12e6183f04d4 121 while(rcv_num_byt);
Kovalev_D 22:12e6183f04d4 122 rcv_num_byt_old = rcv_num_byt;
Kovalev_D 22:12e6183f04d4 123 #if defined UART1REC
Kovalev_D 22:12e6183f04d4 124 LPC_UART1->FCR |= RX_FIFO_Reset;
Kovalev_D 22:12e6183f04d4 125 #else
Kovalev_D 22:12e6183f04d4 126 LPC_UART0->FCR |= RX_FIFO_Reset;
Kovalev_D 22:12e6183f04d4 127 #endif
Kovalev_D 22:12e6183f04d4 128 // L1_Rc_err (TIMEOUT_ERR);
Kovalev_D 22:12e6183f04d4 129 ToWaitEnd = 0;
Kovalev_D 22:12e6183f04d4 130 return;
Kovalev_D 22:12e6183f04d4 131 }
Kovalev_D 22:12e6183f04d4 132 if (rcv_num_byt_old == rcv_num_byt) //e. we have not received any new bytes
Kovalev_D 22:12e6183f04d4 133 {
Kovalev_D 22:12e6183f04d4 134 if (ToWaitEnd) ToWaitEnd++;
Kovalev_D 22:12e6183f04d4 135 return;
Kovalev_D 22:12e6183f04d4 136 }
Kovalev_D 22:12e6183f04d4 137 rcv_num_byt_old = rcv_num_byt;
Kovalev_D 22:12e6183f04d4 138
Kovalev_D 22:12e6183f04d4 139 if ((rcv_num_byt < 6) || ((rcv_num_byt & 0x0001) == 1))
Kovalev_D 22:12e6183f04d4 140 {
Kovalev_D 22:12e6183f04d4 141 ToWaitEnd++;
Kovalev_D 22:12e6183f04d4 142 return;
Kovalev_D 22:12e6183f04d4 143 }
Kovalev_D 22:12e6183f04d4 144
Kovalev_D 22:12e6183f04d4 145 if ((!ToWaitEnd) && (rcv_num_byt > 1)) //e. the header of packet has not recieved //r. îæèäàåì íà÷àëî ïàêåòà
Kovalev_D 22:12e6183f04d4 146 if ((rcv_buf[0] != 0xCC) || (( rcv_buf[1] > 2) && ( rcv_buf[1] != 0x1F)))
Kovalev_D 22:12e6183f04d4 147 {
Kovalev_D 22:12e6183f04d4 148 // L1_Rc_err (HEADER_ERR);
Kovalev_D 22:12e6183f04d4 149 ErrReg |= 5;
Kovalev_D 22:12e6183f04d4 150 ToWaitEnd++;
Kovalev_D 22:12e6183f04d4 151 return;
Kovalev_D 22:12e6183f04d4 152 }
Kovalev_D 22:12e6183f04d4 153 // if (ErrReg != 0) //e. trying of recovering of packet //r. ñïàñåíèå ñëåäóþùåãî ïàêåòà
Kovalev_D 22:12e6183f04d4 154 // PacketSafing();
Kovalev_D 22:12e6183f04d4 155
Kovalev_D 22:12e6183f04d4 156
Kovalev_D 22:12e6183f04d4 157 if (rcv_num_byt == 6)
Kovalev_D 22:12e6183f04d4 158 {
Kovalev_D 22:12e6183f04d4 159 if ((rcv_buf[2] == 0x0A) || (rcv_buf[2] == 0xE0) || (rcv_buf[2] == 0xE4) || (rcv_buf[2] == 0xE6) || (rcv_buf[2] == 0xE8))
Kovalev_D 22:12e6183f04d4 160 { //e. packet length is not valid, so we have the error //r. îøèáêà ðàçìåðà ïàêåòà
Kovalev_D 22:12e6183f04d4 161 ToWaitEnd++;
Kovalev_D 22:12e6183f04d4 162 return;
Kovalev_D 22:12e6183f04d4 163 }
Kovalev_D 22:12e6183f04d4 164
Kovalev_D 22:12e6183f04d4 165 }
Kovalev_D 22:12e6183f04d4 166 else if (rcv_num_byt == 8)
Kovalev_D 22:12e6183f04d4 167 {
Kovalev_D 22:12e6183f04d4 168 if ((rcv_buf[2] == 0xE0) || (rcv_buf[2] == 0xE4))
Kovalev_D 22:12e6183f04d4 169 {
Kovalev_D 22:12e6183f04d4 170 ToWaitEnd++;
Kovalev_D 22:12e6183f04d4 171 return;
Kovalev_D 22:12e6183f04d4 172 }
Kovalev_D 22:12e6183f04d4 173 }
Kovalev_D 22:12e6183f04d4 174 if (check_lcc() != 0) //e. checksum is bad //r.êîíòðîëüíûå ñóììû íå ðàâíû
Kovalev_D 22:12e6183f04d4 175 {
Kovalev_D 22:12e6183f04d4 176
Kovalev_D 22:12e6183f04d4 177 return;
Kovalev_D 22:12e6183f04d4 178 }
Kovalev_D 22:12e6183f04d4 179 else //e. cheksum is not bad //r.êîíòðîëüíûå ñóììû ðàâíû
Kovalev_D 22:12e6183f04d4 180 {
Kovalev_D 22:12e6183f04d4 181 rcv_Rdy = 1;
Kovalev_D 22:12e6183f04d4 182 }
Kovalev_D 22:12e6183f04d4 183 ToWaitEnd = 0;
Kovalev_D 22:12e6183f04d4 184
Kovalev_D 22:12e6183f04d4 185 return;
Kovalev_D 22:12e6183f04d4 186
Kovalev_D 22:12e6183f04d4 187 }
Kovalev_D 22:12e6183f04d4 188 /*
Kovalev_D 22:12e6183f04d4 189 void L1_Rc_err (int Error) //e. error fixing and reciever restart //r. ìîäóëü ôèêñàöèè îøèáêè è ïåðåçàïóñêà ïðèåìíèêà
Kovalev_D 22:12e6183f04d4 190 {
Kovalev_D 22:12e6183f04d4 191 int temp;
Kovalev_D 22:12e6183f04d4 192 line_sts |= Error;
Kovalev_D 22:12e6183f04d4 193 temp = Copy_SRgR & (~Rcv_Rdy);
Kovalev_D 22:12e6183f04d4 194 io_space_write(Sys_RgR, temp);
Kovalev_D 22:12e6183f04d4 195 temp |= Rcv_Rdy;
Kovalev_D 22:12e6183f04d4 196 asm("nop;");
Kovalev_D 22:12e6183f04d4 197 io_space_write(Sys_RgR, temp);
Kovalev_D 22:12e6183f04d4 198 return;
Kovalev_D 22:12e6183f04d4 199 }
Kovalev_D 22:12e6183f04d4 200 */
Kovalev_D 22:12e6183f04d4 201
Kovalev_D 22:12e6183f04d4 202 /******************************************************************************
Kovalev_D 22:12e6183f04d4 203 ** Function name: transm_DAT
Kovalev_D 22:12e6183f04d4 204 **
Kovalev_D 22:12e6183f04d4 205 ** Descriptions: transmit process preparation
Kovalev_D 22:12e6183f04d4 206 **
Kovalev_D 22:12e6183f04d4 207 ** parameters: None
Kovalev_D 22:12e6183f04d4 208 ** Returned value: None
Kovalev_D 22:12e6183f04d4 209 **
Kovalev_D 22:12e6183f04d4 210 ******************************************************************************/
Kovalev_D 22:12e6183f04d4 211
Kovalev_D 22:12e6183f04d4 212
Kovalev_D 22:12e6183f04d4 213 void transm_DAT(void)
Kovalev_D 22:12e6183f04d4 214 {
Kovalev_D 22:12e6183f04d4 215 uint32_t param, param_byte, CRC;
Kovalev_D 22:12e6183f04d4 216 int32_t *trans_param;
Kovalev_D 22:12e6183f04d4 217
Kovalev_D 22:12e6183f04d4 218 if ((LPC_UART1->LSR & TRANS_SHIFT_BUF_EMPTY)) //r. ïåðåäàþùèé áóôåð ïóñò
Kovalev_D 22:12e6183f04d4 219 if (!( LPC_GPDMACH1->CConfig & (1<<17)))
Kovalev_D 22:12e6183f04d4 220 LPC_GPIO2->FIOCLR |= 8; //switch off UART1 driver
Kovalev_D 22:12e6183f04d4 221
Kovalev_D 22:12e6183f04d4 222 if (trm_ena == 0)
Kovalev_D 22:12e6183f04d4 223 {
Kovalev_D 22:12e6183f04d4 224 // LPC_GPIO1->FIOCLR = (0x01<<30); //r.ïåðåäà÷à òðåáóåòñÿ?
Kovalev_D 22:12e6183f04d4 225 return; //r. åñëè íåò, âîçâðàò
Kovalev_D 22:12e6183f04d4 226 }
Kovalev_D 22:12e6183f04d4 227
Kovalev_D 22:12e6183f04d4 228 if (!(LPC_UART1->LSR & TRANS_SHIFT_BUF_EMPTY)) //r. ïåðåäàþùèé áóôåð ïóñò
Kovalev_D 22:12e6183f04d4 229 return;
Kovalev_D 22:12e6183f04d4 230
Kovalev_D 22:12e6183f04d4 231 if ( LPC_GPDMACH1->CConfig & (1<<17)) //r. åñëè êàíàë ïåðåäà÷è çàíÿò, æäàòü
Kovalev_D 22:12e6183f04d4 232 return;
Kovalev_D 22:12e6183f04d4 233
Kovalev_D 22:12e6183f04d4 234 //#if defined UART1TEST
Kovalev_D 22:12e6183f04d4 235 // if (LPC_SC->DMAREQSEL == 0x8) //e. DMA request from UART
Kovalev_D 22:12e6183f04d4 236 // LPC_GPIO2->FIOSET |= (1<<3); //e. set enable UART bit
Kovalev_D 22:12e6183f04d4 237 //#endif
Kovalev_D 22:12e6183f04d4 238
Kovalev_D 22:12e6183f04d4 239 trm_ena = 0; //r. ñáðîñèòü ôëàã ðàçðåøåíèÿ ïåðåäà÷è
Kovalev_D 22:12e6183f04d4 240
Kovalev_D 22:12e6183f04d4 241 trm_num_byt = 2;
Kovalev_D 22:12e6183f04d4 242
Kovalev_D 22:12e6183f04d4 243 trm_buf[0] = 0x00dd; //r. çàãîëîâîê ïàêåòà
Kovalev_D 22:12e6183f04d4 244 trm_buf[1] = Device_blk.Str.My_Addres; //r. àäðåñ ïðèáîðà
Kovalev_D 22:12e6183f04d4 245
Kovalev_D 22:12e6183f04d4 246 CRC = trm_buf[1]; //r.èíèöèàëèçàöèÿ ñ÷åò÷èêà êîíòðîëüíîé ñóììû
Kovalev_D 22:12e6183f04d4 247 for ( param = 0; param < num_of_par; param++) //r.öèêë ôîðìèðîâàíèÿ áëîêà äàííûõ ïàêåòà
Kovalev_D 22:12e6183f04d4 248 {
Kovalev_D 22:12e6183f04d4 249 trans_param = (int32_t *)addr_param[param]; //r. ÷òåíèå àäðåñà îäíîãî èç âûäàâàåìûõ â ïàêåòå ïàðàìåòðîâ
Kovalev_D 22:12e6183f04d4 250
Kovalev_D 22:12e6183f04d4 251 for (param_byte = 0; param_byte < size_param[param]; param_byte++)
Kovalev_D 22:12e6183f04d4 252 {
Kovalev_D 22:12e6183f04d4 253 if ( (param_byte & 0x0001) == 0 ) //r. ñ÷èòûâàåì ñòàðøèé áàéò
Kovalev_D 22:12e6183f04d4 254 trm_buf[trm_num_byt] = (*trans_param >> (8/**(size_param[param]-param_byte-1)*/)) & 0x00ff; //r.ðàçìåùåíèå ïåðåäàâàåìîãî ïàðàìåòðà â ïàêåòå
Kovalev_D 22:12e6183f04d4 255 else
Kovalev_D 22:12e6183f04d4 256 {
Kovalev_D 22:12e6183f04d4 257 trm_buf[trm_num_byt] = *trans_param & 0x00ff;
Kovalev_D 22:12e6183f04d4 258 trans_param ++; //r.ïåðåõîäèì ê ñëåäóþùåé ÿ÷åéêå ïàìÿòè
Kovalev_D 22:12e6183f04d4 259 }
Kovalev_D 22:12e6183f04d4 260 CRC += trm_buf[trm_num_byt]; //r. âû÷èñëåíèå òåêóùåé êîíòðîëüíîé ñóììû
Kovalev_D 22:12e6183f04d4 261 trm_num_byt++; //r. êîëè÷åñòâî áèò, îòïðàâëåííûõ â ïàêåò
Kovalev_D 22:12e6183f04d4 262 }
Kovalev_D 22:12e6183f04d4 263 }
Kovalev_D 22:12e6183f04d4 264 trm_buf[trm_num_byt] = CRC >> 8; //r. çàïèñü êîíòðîëüíîé ñóììû â ïàêåò
Kovalev_D 22:12e6183f04d4 265 trm_buf[trm_num_byt+1] = CRC & 0x00ff;
Kovalev_D 22:12e6183f04d4 266
Kovalev_D 22:12e6183f04d4 267 trm_num_byt += 2;
Kovalev_D 22:12e6183f04d4 268
Kovalev_D 22:12e6183f04d4 269 LPC_GPDMACH1->CSrcAddr = (uint32_t)&trm_buf;
Kovalev_D 22:12e6183f04d4 270
Kovalev_D 22:12e6183f04d4 271 LPC_GPDMACH1->CControl &= ~0xFFF; //e. reset of numer bytes for transmitting
Kovalev_D 22:12e6183f04d4 272 LPC_GPDMACH2->CControl &= ~0xFFF; //e. reset of numer bytes for transmitting
Kovalev_D 22:12e6183f04d4 273
Kovalev_D 22:12e6183f04d4 274 LPC_GPDMACH1->CLLI = 0; //e. linked list is empty
Kovalev_D 22:12e6183f04d4 275
Kovalev_D 22:12e6183f04d4 276 if (trm_num_byt > 16) //e. a packet is too long for FIFO
Kovalev_D 22:12e6183f04d4 277 {
Kovalev_D 22:12e6183f04d4 278 LPC_GPDMACH1->CControl |= 16; //e. set length of first packet part
Kovalev_D 22:12e6183f04d4 279 LPC_GPDMACH1->CLLI = (uint32_t)&LLI0_TypeDef; //e. initialize chain for other parts transmitting
Kovalev_D 22:12e6183f04d4 280 }
Kovalev_D 22:12e6183f04d4 281 else
Kovalev_D 22:12e6183f04d4 282 LPC_GPDMACH1->CControl |= trm_num_byt;
Kovalev_D 22:12e6183f04d4 283
Kovalev_D 22:12e6183f04d4 284 LPC_GPDMACH2->CControl |= 1; //e. set 1 transfert for enable signal
Kovalev_D 22:12e6183f04d4 285 #if defined UART1TEST
Kovalev_D 22:12e6183f04d4 286 LPC_UART1->TER = 0; //e. disable data output to UART1
Kovalev_D 22:12e6183f04d4 287 #endif
Kovalev_D 22:12e6183f04d4 288 if (Device_Mode < 4) //e. work with internal latch
Kovalev_D 22:12e6183f04d4 289 {
Kovalev_D 22:12e6183f04d4 290 LPC_TIM0->TCR = 1; //e. start timer
Kovalev_D 22:12e6183f04d4 291 //-------------------debug-----------------------------------------
Kovalev_D 22:12e6183f04d4 292 LPC_GPIO2->FIOSET |= 8; //turn on RS-422 driver
Kovalev_D 22:12e6183f04d4 293 //-------------------debug-----------------------------------------
Kovalev_D 22:12e6183f04d4 294
Kovalev_D 22:12e6183f04d4 295 LPC_GPDMACH1->CConfig |= DMAChannelEn; //e. DMA for UART transmition
Kovalev_D 22:12e6183f04d4 296 //LPC_GPIO1->FIOSET = (0x1<<30);
Kovalev_D 22:12e6183f04d4 297
Kovalev_D 22:12e6183f04d4 298 }
Kovalev_D 22:12e6183f04d4 299
Kovalev_D 22:12e6183f04d4 300 LPC_GPDMACH2->CConfig |= DMAChannelEn; //e. DMA for enable signal
Kovalev_D 22:12e6183f04d4 301 return;
Kovalev_D 22:12e6183f04d4 302 }
Kovalev_D 22:12e6183f04d4 303 /******************************************************************************
Kovalev_D 22:12e6183f04d4 304 ** Function name: DMA_Init
Kovalev_D 22:12e6183f04d4 305 **
Kovalev_D 22:12e6183f04d4 306 ** Descriptions:
Kovalev_D 22:12e6183f04d4 307 **
Kovalev_D 22:12e6183f04d4 308 ** parameters:
Kovalev_D 22:12e6183f04d4 309 ** Returned value:
Kovalev_D 22:12e6183f04d4 310 **
Kovalev_D 22:12e6183f04d4 311 ******************************************************************************/
Kovalev_D 22:12e6183f04d4 312 void DMA_Init( void )
Kovalev_D 22:12e6183f04d4 313 {
Kovalev_D 22:12e6183f04d4 314 /* Enable CLOCK into GPDMA controller */
Kovalev_D 22:12e6183f04d4 315 LPC_SC->PCONP |= GPDMA_POWER_ON;
Kovalev_D 22:12e6183f04d4 316
Kovalev_D 22:12e6183f04d4 317 /* Select primary function(UART0/1/2/3) in DMA channels,
Kovalev_D 22:12e6183f04d4 318 secondary is timer 0/1/2/3. */
Kovalev_D 22:12e6183f04d4 319 #if defined UART1TEST
Kovalev_D 22:12e6183f04d4 320 LPC_SC->DMAREQSEL = 3;
Kovalev_D 22:12e6183f04d4 321 #endif
Kovalev_D 22:12e6183f04d4 322 //LPC_GPDMA->Sync = (0x1<<DMA_UART0_RX)|(0x1<<DMA_UART1_TX); //synchronization logic is enabled by default
Kovalev_D 22:12e6183f04d4 323 LPC_GPDMA->Config = DMA_ControllerEn | DMA_AHB_Little;
Kovalev_D 22:12e6183f04d4 324 while ( !(LPC_GPDMA->Config & DMA_ControllerEn) ); //wait until DMA_Controller switched on
Kovalev_D 22:12e6183f04d4 325
Kovalev_D 22:12e6183f04d4 326 NVIC_DisableIRQ(DMA_IRQn);
Kovalev_D 22:12e6183f04d4 327 return;
Kovalev_D 22:12e6183f04d4 328 }
Kovalev_D 22:12e6183f04d4 329
Kovalev_D 22:12e6183f04d4 330 /******************************************************************************
Kovalev_D 22:12e6183f04d4 331 ** Function name: UARTInit
Kovalev_D 22:12e6183f04d4 332 **
Kovalev_D 22:12e6183f04d4 333 ** Descriptions: Initialisation of UART on 38400 baud
Kovalev_D 22:12e6183f04d4 334 **
Kovalev_D 22:12e6183f04d4 335 ** parameters: None
Kovalev_D 22:12e6183f04d4 336 ** Returned value: None
Kovalev_D 22:12e6183f04d4 337 **
Kovalev_D 22:12e6183f04d4 338 ******************************************************************************/
Kovalev_D 22:12e6183f04d4 339 void UARTInit(void)
Kovalev_D 22:12e6183f04d4 340 {
Kovalev_D 22:12e6183f04d4 341 uint32_t Fdiv;
Kovalev_D 22:12e6183f04d4 342 uint32_t pclk;
Kovalev_D 22:12e6183f04d4 343 #if !defined UART1TEST
Kovalev_D 22:12e6183f04d4 344 uint32_t baudrate = 38400;
Kovalev_D 22:12e6183f04d4 345 #else
Kovalev_D 22:12e6183f04d4 346 uint32_t baudrate = 38400;
Kovalev_D 22:12e6183f04d4 347 #endif
Kovalev_D 22:12e6183f04d4 348 LPC_SC->PCONP |= (1<<3);
Kovalev_D 22:12e6183f04d4 349
Kovalev_D 22:12e6183f04d4 350 LPC_PINCON->PINSEL0 |= 0x00000050;
Kovalev_D 22:12e6183f04d4 351
Kovalev_D 22:12e6183f04d4 352 pclk = SystemCoreClock/4;
Kovalev_D 22:12e6183f04d4 353
Kovalev_D 22:12e6183f04d4 354 LPC_UART0->LCR = word_length_8 |one_stop_bit |no_parity |back_trans_dis |DLAB_access;
Kovalev_D 22:12e6183f04d4 355 Fdiv = (pclk / 16) / baudrate;
Kovalev_D 22:12e6183f04d4 356 LPC_UART0->DLM = Fdiv / 256;
Kovalev_D 22:12e6183f04d4 357 LPC_UART0->DLL = Fdiv % 256;
Kovalev_D 22:12e6183f04d4 358 LPC_UART0->LCR &= ~DLAB_access;
Kovalev_D 22:12e6183f04d4 359 LPC_UART0->FCR = TX_FIFO_Reset |RX_FIFO_Reset |FIFOs_En |RX_TrigLvl_14; //0x06;
Kovalev_D 22:12e6183f04d4 360 LPC_UART0->IER = 0;//RBR_IntEnabl;
Kovalev_D 22:12e6183f04d4 361
Kovalev_D 22:12e6183f04d4 362 LPC_UART0->FCR |= 0x08; //e. DMA mode select
Kovalev_D 22:12e6183f04d4 363 //+++++++++++++++++++++++enable signal initialization++++++++++++++++++++++++++
Kovalev_D 22:12e6183f04d4 364 LPC_PINCON->PINSEL1 &= ~0x0000C000; //e. select P0.23 as general purpose
Kovalev_D 22:12e6183f04d4 365 LPC_GPIO0->FIODIR |= 0x00800000; //e. P0.23 is output
Kovalev_D 22:12e6183f04d4 366 // LPC_GPIO0->FIOMASK |= 0x007F0000; //e. P0.16..P0.22 is not changed by FIOSET writing
Kovalev_D 22:12e6183f04d4 367 LPC_GPIO0->FIOCLR |= 0x00800000; // e. clear P0.23
Kovalev_D 22:12e6183f04d4 368
Kovalev_D 22:12e6183f04d4 369 return;
Kovalev_D 22:12e6183f04d4 370 }
Kovalev_D 22:12e6183f04d4 371
Kovalev_D 22:12e6183f04d4 372 void UART1_Init(void)
Kovalev_D 22:12e6183f04d4 373 {
Kovalev_D 22:12e6183f04d4 374 uint32_t Fdiv;
Kovalev_D 22:12e6183f04d4 375 uint32_t pclk;
Kovalev_D 22:12e6183f04d4 376 #if !defined UART1TEST
Kovalev_D 22:12e6183f04d4 377 uint32_t baudrate = 256000;
Kovalev_D 22:12e6183f04d4 378 #else
Kovalev_D 22:12e6183f04d4 379 uint32_t baudrate = 38400;
Kovalev_D 22:12e6183f04d4 380 #endif
Kovalev_D 22:12e6183f04d4 381 LPC_SC->PCONP |= (1<<4); //switch on UART1
Kovalev_D 22:12e6183f04d4 382
Kovalev_D 22:12e6183f04d4 383 LPC_PINCON->PINSEL4 |= (2<<0)|(2<<2)|(2<<10)|(2<<14); //P2.0, P2.1, P2.5, P2.7
Kovalev_D 22:12e6183f04d4 384
Kovalev_D 22:12e6183f04d4 385 pclk = SystemCoreClock/4;
Kovalev_D 22:12e6183f04d4 386
Kovalev_D 22:12e6183f04d4 387 LPC_UART1->LCR = word_length_8 |one_stop_bit |no_parity |back_trans_dis |DLAB_access;
Kovalev_D 22:12e6183f04d4 388 Fdiv = (pclk / 16) / baudrate;
Kovalev_D 22:12e6183f04d4 389 LPC_UART1->DLM = Fdiv / 256;
Kovalev_D 22:12e6183f04d4 390 LPC_UART1->DLL = Fdiv % 256;
Kovalev_D 22:12e6183f04d4 391 LPC_UART1->LCR &= ~DLAB_access;
Kovalev_D 22:12e6183f04d4 392 LPC_UART1->FCR = TX_FIFO_Reset |RX_FIFO_Reset |FIFOs_En |RX_TrigLvl_14; //0x06;
Kovalev_D 22:12e6183f04d4 393
Kovalev_D 22:12e6183f04d4 394 LPC_UART1->RS485CTRL = (1<<5); //(1<<4);
Kovalev_D 22:12e6183f04d4 395
Kovalev_D 22:12e6183f04d4 396 LPC_UART1->IER = 0;//RBR_IntEnabl;
Kovalev_D 22:12e6183f04d4 397
Kovalev_D 22:12e6183f04d4 398 LPC_UART1->FCR |= 0x08; //e. DMA mode select
Kovalev_D 22:12e6183f04d4 399 return;
Kovalev_D 22:12e6183f04d4 400 }
Kovalev_D 22:12e6183f04d4 401 //----------------------temp----------------------------
Kovalev_D 22:12e6183f04d4 402 /*int UART0_SendByte (int ucData)
Kovalev_D 22:12e6183f04d4 403 {
Kovalev_D 22:12e6183f04d4 404 // while (!(LPC_UART1->LSR & 0x20));
Kovalev_D 22:12e6183f04d4 405 return (LPC_UART0->THR = ucData);
Kovalev_D 22:12e6183f04d4 406 }*/
Kovalev_D 22:12e6183f04d4 407 //----------------------temp----------------------------
Kovalev_D 22:12e6183f04d4 408 int UART1_SendByte (int ucData)
Kovalev_D 22:12e6183f04d4 409 {
Kovalev_D 22:12e6183f04d4 410 // while (!(LPC_UART1->LSR & 0x20));
Kovalev_D 22:12e6183f04d4 411 return (LPC_UART1->THR = ucData);
Kovalev_D 22:12e6183f04d4 412 }
Kovalev_D 22:12e6183f04d4 413 /******************************************************************************
Kovalev_D 22:12e6183f04d4 414 ** Function name: UART_SwitchSpeed
Kovalev_D 22:12e6183f04d4 415 **
Kovalev_D 22:12e6183f04d4 416 ** Descriptions: Change UART speed
Kovalev_D 22:12e6183f04d4 417 **
Kovalev_D 22:12e6183f04d4 418 ** parameters: Demanded speed
Kovalev_D 22:12e6183f04d4 419 ** Returned value: None
Kovalev_D 22:12e6183f04d4 420 **
Kovalev_D 22:12e6183f04d4 421 ******************************************************************************/
Kovalev_D 22:12e6183f04d4 422 void UART_SwitchSpeed(unsigned Speed)
Kovalev_D 22:12e6183f04d4 423 {
Kovalev_D 22:12e6183f04d4 424 uint32_t Fdiv;
Kovalev_D 22:12e6183f04d4 425 uint32_t pclk;
Kovalev_D 22:12e6183f04d4 426
Kovalev_D 22:12e6183f04d4 427 pclk = SystemCoreClock/4;
Kovalev_D 22:12e6183f04d4 428 #if defined UART1REC
Kovalev_D 22:12e6183f04d4 429 LPC_UART1->LCR |= DLAB_access;
Kovalev_D 22:12e6183f04d4 430 #else
Kovalev_D 22:12e6183f04d4 431 LPC_UART0->LCR |= DLAB_access;
Kovalev_D 22:12e6183f04d4 432 #endif
Kovalev_D 22:12e6183f04d4 433 switch (Speed)
Kovalev_D 22:12e6183f04d4 434 {
Kovalev_D 22:12e6183f04d4 435 case Sp38400:
Kovalev_D 22:12e6183f04d4 436 Fdiv = (pclk / 16) / 38400;
Kovalev_D 22:12e6183f04d4 437 EnablLength = 3240;
Kovalev_D 22:12e6183f04d4 438 break;
Kovalev_D 22:12e6183f04d4 439
Kovalev_D 22:12e6183f04d4 440 case Sp115200:
Kovalev_D 22:12e6183f04d4 441 Fdiv = (pclk / 16) /115200;
Kovalev_D 22:12e6183f04d4 442 EnablLength = 1090;
Kovalev_D 22:12e6183f04d4 443 break;
Kovalev_D 22:12e6183f04d4 444
Kovalev_D 22:12e6183f04d4 445 case Sp460800:
Kovalev_D 22:12e6183f04d4 446 Fdiv = (pclk / 16) / 460800;
Kovalev_D 22:12e6183f04d4 447 break;
Kovalev_D 22:12e6183f04d4 448
Kovalev_D 22:12e6183f04d4 449 case Sp921600:
Kovalev_D 22:12e6183f04d4 450 Fdiv = (pclk / 16) / 921600;
Kovalev_D 22:12e6183f04d4 451 EnablLength = 140;
Kovalev_D 22:12e6183f04d4 452 break;
Kovalev_D 22:12e6183f04d4 453
Kovalev_D 22:12e6183f04d4 454 }
Kovalev_D 22:12e6183f04d4 455 #if defined UART1REC
Kovalev_D 22:12e6183f04d4 456 LPC_UART1->DLM = Fdiv / 256;
Kovalev_D 22:12e6183f04d4 457 LPC_UART1->DLL = Fdiv % 256;
Kovalev_D 22:12e6183f04d4 458 LPC_UART1->LCR &= ~DLAB_access;
Kovalev_D 22:12e6183f04d4 459 #else
Kovalev_D 22:12e6183f04d4 460 LPC_UART0->DLM = Fdiv / 256;
Kovalev_D 22:12e6183f04d4 461 LPC_UART0->DLL = Fdiv % 256;
Kovalev_D 22:12e6183f04d4 462 LPC_UART0->LCR &= ~DLAB_access;
Kovalev_D 22:12e6183f04d4 463 #endif
Kovalev_D 22:12e6183f04d4 464 }
Kovalev_D 22:12e6183f04d4 465 /******************************************************************************
Kovalev_D 22:12e6183f04d4 466 ** Function name: UART_DMA_Init
Kovalev_D 22:12e6183f04d4 467 **
Kovalev_D 22:12e6183f04d4 468 ** Descriptions: Initialisation of DMA channel for UART transmitter
Kovalev_D 22:12e6183f04d4 469 **
Kovalev_D 22:12e6183f04d4 470 ** parameters: None
Kovalev_D 22:12e6183f04d4 471 ** Returned value: None
Kovalev_D 22:12e6183f04d4 472 **
Kovalev_D 22:12e6183f04d4 473 ******************************************************************************/
Kovalev_D 22:12e6183f04d4 474 void UART_DMA_Init()
Kovalev_D 22:12e6183f04d4 475 {
Kovalev_D 22:12e6183f04d4 476 //+++++++++++++++++config channel for UART0+++++++++++++++++++++++++++++++++++++++++++++++
Kovalev_D 22:12e6183f04d4 477 LPC_GPDMACH1->CConfig &= ~DMAChannelEn;
Kovalev_D 22:12e6183f04d4 478
Kovalev_D 22:12e6183f04d4 479 LPC_GPDMA->IntTCClear = DMA1_IntTCClear;
Kovalev_D 22:12e6183f04d4 480 LPC_GPDMA->IntErrClr = DMA1_IntErrClear;
Kovalev_D 22:12e6183f04d4 481
Kovalev_D 22:12e6183f04d4 482 LPC_GPDMACH1->CSrcAddr = (uint32_t)&trm_buf;
Kovalev_D 22:12e6183f04d4 483 LPC_GPDMACH1->CDestAddr = UART1_DMA_TX_DST;
Kovalev_D 22:12e6183f04d4 484 LPC_GPDMACH1->CControl = SrcBSize_1 | DstBSize_1 | SrcWidth_8b | DstWidth_8b | SrcInc | DstFixed | TCIntDisabl;
Kovalev_D 22:12e6183f04d4 485 #if defined UART1TEST
Kovalev_D 22:12e6183f04d4 486 LPC_GPDMACH1->CConfig |= MaskTCInt | MaskErrInt | DMA_MEMORY | DstDMA_UART1_TX |(M2P << 11);
Kovalev_D 22:12e6183f04d4 487 #else
Kovalev_D 22:12e6183f04d4 488 g LPC_GPDMACH1->CConfig |= MaskTCInt | MaskErrInt | DMA_MEMORY | DstDMA_UART0_TX |(M2P << 11);
Kovalev_D 22:12e6183f04d4 489 #endif
Kovalev_D 22:12e6183f04d4 490
Kovalev_D 22:12e6183f04d4 491 EnablDMA = (LPC_GPDMACH1->CConfig)|DMAChannelEn; //save register content for DMA starting in multidrop mode
Kovalev_D 22:12e6183f04d4 492 //**********for Rate mode output*****************************
Kovalev_D 22:12e6183f04d4 493 #if defined UART1TEST
Kovalev_D 22:12e6183f04d4 494 LLI1_TypeDef[0] = (uint32_t)&trm_buf[32];
Kovalev_D 22:12e6183f04d4 495 LLI1_TypeDef[1] = UART1_DMA_TX_DST;
Kovalev_D 22:12e6183f04d4 496 LLI1_TypeDef[2] = 0;
Kovalev_D 22:12e6183f04d4 497 LLI1_TypeDef[3] = (12 & 0x0FFF) | SrcBSize_1 | DstBSize_1 | SrcWidth_8b | DstWidth_8b | SrcInc | DstFixed | TCIntDisabl;
Kovalev_D 22:12e6183f04d4 498
Kovalev_D 22:12e6183f04d4 499 LLI0_TypeDef[0] = (uint32_t)&trm_buf[16];
Kovalev_D 22:12e6183f04d4 500 LLI0_TypeDef[1] = UART1_DMA_TX_DST;
Kovalev_D 22:12e6183f04d4 501 LLI0_TypeDef[2] = (uint32_t)&LLI1_TypeDef;
Kovalev_D 22:12e6183f04d4 502 LLI0_TypeDef[3] = (16 & 0x0FFF) | SrcBSize_1 | DstBSize_1 | SrcWidth_8b | DstWidth_8b | SrcInc | DstFixed | TCIntDisabl;
Kovalev_D 22:12e6183f04d4 503 #else
Kovalev_D 22:12e6183f04d4 504 LLI1_TypeDef[0] = (uint32_t)&trm_buf[32];
Kovalev_D 22:12e6183f04d4 505 LLI1_TypeDef[1] = UART0_DMA_TX_DST;
Kovalev_D 22:12e6183f04d4 506 LLI1_TypeDef[2] = 0;
Kovalev_D 22:12e6183f04d4 507 LLI1_TypeDef[3] = (12 & 0x0FFF) | SrcBSize_1 | DstBSize_1 | SrcWidth_8b | DstWidth_8b | SrcInc | DstFixed | TCIntDisabl;
Kovalev_D 22:12e6183f04d4 508
Kovalev_D 22:12e6183f04d4 509 LLI0_TypeDef[0] = (uint32_t)&trm_buf[16];
Kovalev_D 22:12e6183f04d4 510 LLI0_TypeDef[1] = UART0_DMA_TX_DST;
Kovalev_D 22:12e6183f04d4 511 LLI0_TypeDef[2] = (uint32_t)&LLI1_TypeDef;
Kovalev_D 22:12e6183f04d4 512 LLI0_TypeDef[3] = (16 & 0x0FFF)|SrcBSize_1 |DstBSize_1 |SrcWidth_8b
Kovalev_D 22:12e6183f04d4 513 |DstWidth_8b|SrcInc |DstFixed |TCIntDisabl;
Kovalev_D 22:12e6183f04d4 514 #endif
Kovalev_D 22:12e6183f04d4 515 //++++++++++++++++++++++++++config channel for transmit enable signal+++++++++++++++++++
Kovalev_D 22:12e6183f04d4 516 LPC_GPDMACH2->CConfig &= ~DMAChannelEn;
Kovalev_D 22:12e6183f04d4 517
Kovalev_D 22:12e6183f04d4 518 LPC_GPDMA->IntTCClear = DMA2_IntTCClear;
Kovalev_D 22:12e6183f04d4 519 LPC_GPDMA->IntErrClr = DMA2_IntErrClear;
Kovalev_D 22:12e6183f04d4 520
Kovalev_D 22:12e6183f04d4 521 LPC_GPDMACH2->CSrcAddr = (uint32_t)&EnablTx; //e. content of TX UART1 enable register
Kovalev_D 22:12e6183f04d4 522 LPC_GPDMACH2->CDestAddr = 0x40010030; //e. address of TX UART1 enable register (U1TER)
Kovalev_D 22:12e6183f04d4 523
Kovalev_D 22:12e6183f04d4 524 LPC_GPDMACH2->CControl = SrcBSize_4 |DstBSize_4
Kovalev_D 22:12e6183f04d4 525 |SrcWidth_8b |DstWidth_8b|SrcFixed |DstFixed |TCIntEnabl;
Kovalev_D 22:12e6183f04d4 526
Kovalev_D 22:12e6183f04d4 527 LPC_GPDMACH2->CConfig |= MaskTCInt |MaskErrInt
Kovalev_D 22:12e6183f04d4 528 |SrcDMA_UART0_RX |DstDMA_UART0_RX|(M2P << 11);
Kovalev_D 22:12e6183f04d4 529 LPC_GPDMACH2->CLLI = 0; //e. linked list is empty
Kovalev_D 22:12e6183f04d4 530
Kovalev_D 22:12e6183f04d4 531 //++++++++++++++++++++++++++config channel for DMA1 enable signal+++++++++++++++++++
Kovalev_D 22:12e6183f04d4 532 #if defined UART1TEST
Kovalev_D 22:12e6183f04d4 533 LPC_GPDMACH4->CConfig &= ~DMAChannelEn;
Kovalev_D 22:12e6183f04d4 534
Kovalev_D 22:12e6183f04d4 535 LPC_GPDMA->IntTCClear = DMA4_IntTCClear;
Kovalev_D 22:12e6183f04d4 536 LPC_GPDMA->IntErrClr = DMA4_IntErrClear;
Kovalev_D 22:12e6183f04d4 537
Kovalev_D 22:12e6183f04d4 538 LPC_GPDMACH4->CSrcAddr = (uint32_t)&EnablDMA; //e. content of TX UART1 enable register
Kovalev_D 22:12e6183f04d4 539 LPC_GPDMACH4->CDestAddr = 0x50004130; //e. address of DMA1CConfig register
Kovalev_D 22:12e6183f04d4 540
Kovalev_D 22:12e6183f04d4 541 LPC_GPDMACH4->CControl = SrcBSize_4 |DstBSize_4
Kovalev_D 22:12e6183f04d4 542 |SrcWidth_8b |DstWidth_8b|SrcFixed |DstFixed |TCIntEnabl;
Kovalev_D 22:12e6183f04d4 543
Kovalev_D 22:12e6183f04d4 544 LPC_GPDMACH4->CConfig |= MaskTCInt |MaskErrInt
Kovalev_D 22:12e6183f04d4 545 |SrcDMA_UART0_TX |DstDMA_UART0_TX|(M2P << 11);
Kovalev_D 22:12e6183f04d4 546 LPC_GPDMACH4->CLLI = 0; //e. linked list is empty
Kovalev_D 22:12e6183f04d4 547 #endif
Kovalev_D 22:12e6183f04d4 548 }
Kovalev_D 22:12e6183f04d4 549 /******************************************************************************
Kovalev_D 22:12e6183f04d4 550 ** End Of File
Kovalev_D 22:12e6183f04d4 551 ******************************************************************************/