Gerrie de Jager / Mbed 2 deprecated Creatron_RS485

Dependencies:   mbed

Committer:
creatron
Date:
Tue Nov 11 16:01:12 2014 +0000
Revision:
0:044dfba47660
Child:
1:7091401482c5
Flashing led

Who changed what in which revision?

UserRevisionLine numberNew contents of line
creatron 0:044dfba47660 1 #include "mbed.h"
creatron 0:044dfba47660 2
creatron 0:044dfba47660 3 #include "RawSerial.h"
creatron 0:044dfba47660 4 #include "dlms_comms.h"
creatron 0:044dfba47660 5
creatron 0:044dfba47660 6 //#define DEBUG_DLMS_COMMS
creatron 0:044dfba47660 7
creatron 0:044dfba47660 8 // Instantiate the raw serial (2nd uart) Tx then Rx
creatron 0:044dfba47660 9 RawSerial rs485(PA_9, PA_10);
creatron 0:044dfba47660 10 // pin to switch the rs485 buffer direction
creatron 0:044dfba47660 11 DigitalOut dir_485 (PB_0);
creatron 0:044dfba47660 12
creatron 0:044dfba47660 13 /** ---------------------------------------------------------------------------
creatron 0:044dfba47660 14 * @brief C O N S T R U C T O R
creatron 0:044dfba47660 15 */
creatron 0:044dfba47660 16 dlms_comms::dlms_comms (void)
creatron 0:044dfba47660 17 {
creatron 0:044dfba47660 18 // enable the rs485 buffer receiver,
creatron 0:044dfba47660 19 dir_485 = 0;
creatron 0:044dfba47660 20
creatron 0:044dfba47660 21 // clear the pointers and ring buffer
creatron 0:044dfba47660 22 rx_head_ptr = 0;
creatron 0:044dfba47660 23 rx_tail_ptr = 0;
creatron 0:044dfba47660 24 memset (rx_buffer, 0, sizeof(rx_buffer));
creatron 0:044dfba47660 25
creatron 0:044dfba47660 26 // // attach the receiver input to 'run' a method
creatron 0:044dfba47660 27 // // when characters received
creatron 0:044dfba47660 28 // rs485.attach(this,
creatron 0:044dfba47660 29 // &dlms_comms::Rx_interrupt,
creatron 0:044dfba47660 30 // RawSerial::RxIrq);
creatron 0:044dfba47660 31 // transmit empty flag .. need to set buffer
creatron 0:044dfba47660 32 // in receive mode again after we have transmitted
creatron 0:044dfba47660 33 // all data characters
creatron 0:044dfba47660 34 rs485.attach(this,
creatron 0:044dfba47660 35 &dlms_comms::Tx_interrupt,
creatron 0:044dfba47660 36 RawSerial::TxIrq);
creatron 0:044dfba47660 37 timer = NULL;
creatron 0:044dfba47660 38 debug_uart = NULL;
creatron 0:044dfba47660 39 }
creatron 0:044dfba47660 40 /** ---------------------------------------------------------------------------
creatron 0:044dfba47660 41 * @brief bq34z110::init_port_expander Put all ports in INPUT mode
creatron 0:044dfba47660 42 * @param parent_uart The debug uart class pionter
creatron 0:044dfba47660 43 * @param parent_timer The main timer (system tick) class pointer
creatron 0:044dfba47660 44 */
creatron 0:044dfba47660 45 void dlms_comms::init (RawSerial * parent_uart,
creatron 0:044dfba47660 46 Timer * parent_timer)
creatron 0:044dfba47660 47 {
creatron 0:044dfba47660 48 // we use the parent timer and debug port
creatron 0:044dfba47660 49 debug_uart = parent_uart;
creatron 0:044dfba47660 50 timer = parent_timer;
creatron 0:044dfba47660 51 //#ifdef DEBUG_DLMS_COMMS
creatron 0:044dfba47660 52 debug_uart->printf (" init_dlms_comms..\r\n");
creatron 0:044dfba47660 53 //#endif
creatron 0:044dfba47660 54 }
creatron 0:044dfba47660 55 /** ---------------------------------------------------------------------------
creatron 0:044dfba47660 56 * @brief dlms_comms::initialise This method initialise the rs485 comms port
creatron 0:044dfba47660 57 *
creatron 0:044dfba47660 58 * @param baudrate The RS485 baudrate
creatron 0:044dfba47660 59 * @param bits The RS485 number of bits (8)
creatron 0:044dfba47660 60 * @param parity The parity required 'n','o', 'e'
creatron 0:044dfba47660 61 * @param stop_bits The number of stop bits 1 or 2
creatron 0:044dfba47660 62 */
creatron 0:044dfba47660 63 void dlms_comms::initialise (INT_16 baudrate,
creatron 0:044dfba47660 64 UINT_8 bits,
creatron 0:044dfba47660 65 UINT_8 parity,
creatron 0:044dfba47660 66 UINT_8 stop_bits )
creatron 0:044dfba47660 67 {
creatron 0:044dfba47660 68 // default comms parameters
creatron 0:044dfba47660 69 SerialBase::Parity my_parity = SerialBase::None;
creatron 0:044dfba47660 70 irq_count = 0;
creatron 0:044dfba47660 71 // set the class baudrate
creatron 0:044dfba47660 72 rs485.baud(baudrate);
creatron 0:044dfba47660 73 // enable the receiver on the tranceiver buffer chip
creatron 0:044dfba47660 74 dir_485 = 0;
creatron 0:044dfba47660 75 // clear the ring buffer
creatron 0:044dfba47660 76 rx_head_ptr = 0;
creatron 0:044dfba47660 77 rx_tail_ptr = 0;
creatron 0:044dfba47660 78 memset (rx_buffer, 0, sizeof(rx_buffer));
creatron 0:044dfba47660 79 // set the enum parity as required by class
creatron 0:044dfba47660 80 switch (parity)
creatron 0:044dfba47660 81 {
creatron 0:044dfba47660 82 default:
creatron 0:044dfba47660 83 case 'n' :
creatron 0:044dfba47660 84 my_parity = SerialBase::None;
creatron 0:044dfba47660 85 break;
creatron 0:044dfba47660 86 case 'o':
creatron 0:044dfba47660 87 my_parity = SerialBase::Odd;
creatron 0:044dfba47660 88 break;
creatron 0:044dfba47660 89 case 'e':
creatron 0:044dfba47660 90 my_parity = SerialBase::Even;
creatron 0:044dfba47660 91 break;
creatron 0:044dfba47660 92 }
creatron 0:044dfba47660 93 // lets doit .. config the rs485 now
creatron 0:044dfba47660 94 rs485.format((int) bits,
creatron 0:044dfba47660 95 my_parity,
creatron 0:044dfba47660 96 (int) stop_bits);
creatron 0:044dfba47660 97 # ifdef DEBUG_DLMS_COMMS
creatron 0:044dfba47660 98 debug_uart->printf (" init_dlms_comms..Baudrate (%d) %d bits Parity=%c\r\n",
creatron 0:044dfba47660 99 baudrate, bits, parity);
creatron 0:044dfba47660 100 # endif
creatron 0:044dfba47660 101 // dummy send packet to rs485
creatron 0:044dfba47660 102 //send_packet ("\r\nHello cruel world\r\n",12);
creatron 0:044dfba47660 103 }
creatron 0:044dfba47660 104 /** ---------------------------------------------------------------------------
creatron 0:044dfba47660 105 * @brief dlms_comms::get_dir485 . This method returns the state of the rs485
creatron 0:044dfba47660 106 * direction
creatron 0:044dfba47660 107 */
creatron 0:044dfba47660 108 bool dlms_comms::get_dir485 (void)
creatron 0:044dfba47660 109 {
creatron 0:044dfba47660 110 return dir_485;
creatron 0:044dfba47660 111 }
creatron 0:044dfba47660 112 /** ---------------------------------------------------------------------------
creatron 0:044dfba47660 113 * @brief dlms_comms::Tx_interrupt
creatron 0:044dfba47660 114 */
creatron 0:044dfba47660 115 void dlms_comms::Tx_interrupt(void)
creatron 0:044dfba47660 116 {
creatron 0:044dfba47660 117 irq_count++;
creatron 0:044dfba47660 118 // enable the receiver, we are finito with the transmission of characters
creatron 0:044dfba47660 119 // this changes the direction on the transceiver buffer
creatron 0:044dfba47660 120 if (dir_485 == 1)
creatron 0:044dfba47660 121 dir_485 = 0;
creatron 0:044dfba47660 122 }
creatron 0:044dfba47660 123 /** ---------------------------------------------------------------------------
creatron 0:044dfba47660 124 * @brief dlms_comms::Rx_interrupt . This method received all characters from
creatron 0:044dfba47660 125 * the uart and saved it in a ring buffer, 256 bytes long. The CPU only has 16
creatron 0:044dfba47660 126 * byte fifo, this makes it a 256 bit fifo
creatron 0:044dfba47660 127 */
creatron 0:044dfba47660 128 void dlms_comms::Rx_interrupt(void)
creatron 0:044dfba47660 129 {
creatron 0:044dfba47660 130 UINT_8 value;
creatron 0:044dfba47660 131 // read the uart and place character in ring buffer
creatron 0:044dfba47660 132 value = rs485.getc();
creatron 0:044dfba47660 133 rx_buffer[rx_head_ptr++] = value;
creatron 0:044dfba47660 134 }
creatron 0:044dfba47660 135 /** ---------------------------------------------------------------------------
creatron 0:044dfba47660 136 * @brief dlms_comms::available This method return if we have any characters
creatron 0:044dfba47660 137 * available (received on the rs485 port)
creatron 0:044dfba47660 138 * @return true if characters received on the rs485
creatron 0:044dfba47660 139 */
creatron 0:044dfba47660 140 bool dlms_comms::char_available (void)
creatron 0:044dfba47660 141 {
creatron 0:044dfba47660 142 if (rx_head_ptr == rx_tail_ptr)
creatron 0:044dfba47660 143 // nope
creatron 0:044dfba47660 144 return false;
creatron 0:044dfba47660 145 else
creatron 0:044dfba47660 146 return true;
creatron 0:044dfba47660 147 }
creatron 0:044dfba47660 148 /** ---------------------------------------------------------------------------
creatron 0:044dfba47660 149 * @brief dlms_comms::get_char This method return the last character received
creatron 0:044dfba47660 150 * on the rs485 port
creatron 0:044dfba47660 151 * @return Unsigned byte
creatron 0:044dfba47660 152 * @note The user must make sure that characters are available before, else
creatron 0:044dfba47660 153 * this method shall wait for the next character, no timeouts yet
creatron 0:044dfba47660 154 */
creatron 0:044dfba47660 155 UINT_8 dlms_comms::get_char (void)
creatron 0:044dfba47660 156 {
creatron 0:044dfba47660 157 // we have to wait for at least on charcter in the ring buffer
creatron 0:044dfba47660 158 while (char_available() == false);
creatron 0:044dfba47660 159 // return the character
creatron 0:044dfba47660 160 return (rx_buffer[rx_tail_ptr++]);
creatron 0:044dfba47660 161 }
creatron 0:044dfba47660 162 /** ---------------------------------------------------------------------------
creatron 0:044dfba47660 163 * @brief dlms_comms::send_packet This method sends a serial packet data to the
creatron 0:044dfba47660 164 * rs485 bus, the directoion of the tranceiver chip is changed to transmit and
creatron 0:044dfba47660 165 * the packet is tranmitted.
creatron 0:044dfba47660 166 * @param ptr Pointer address for start of the packet
creatron 0:044dfba47660 167 * @param length Packet length
creatron 0:044dfba47660 168 * @note The direction is changed with a interrupt when the transmitter
creatron 0:044dfba47660 169 * is empty
creatron 0:044dfba47660 170 */
creatron 0:044dfba47660 171 void dlms_comms::send_packet (const UINT_8 *ptr,
creatron 0:044dfba47660 172 const UINT_8 length)
creatron 0:044dfba47660 173 {
creatron 0:044dfba47660 174 // local stack variable
creatron 0:044dfba47660 175 UINT_8 * tmp_ptr =(UINT_8 *) ptr;
creatron 0:044dfba47660 176
creatron 0:044dfba47660 177 // change the tranceiver direction to output
creatron 0:044dfba47660 178 dir_485 = 1;
creatron 0:044dfba47660 179 for (UINT_8 i= 0; i < length; i++)
creatron 0:044dfba47660 180 {
creatron 0:044dfba47660 181 rs485.putc (*tmp_ptr++);
creatron 0:044dfba47660 182 }
creatron 0:044dfba47660 183 }
creatron 0:044dfba47660 184 UINT_64 dlms_comms::ret_irq_count (void)
creatron 0:044dfba47660 185 {
creatron 0:044dfba47660 186 return irq_count;
creatron 0:044dfba47660 187 }
creatron 0:044dfba47660 188 bool dlms_comms::poll_rs485(void)
creatron 0:044dfba47660 189 {
creatron 0:044dfba47660 190 if (rs485.readable ())
creatron 0:044dfba47660 191 {
creatron 0:044dfba47660 192 Rx_interrupt();
creatron 0:044dfba47660 193 return true;
creatron 0:044dfba47660 194 }
creatron 0:044dfba47660 195 return false;
creatron 0:044dfba47660 196 }
creatron 0:044dfba47660 197 //----[ the end ]--------------------------------------------------------------