// initializes the spi0 for supplied configuration static void raspicomm_max3140_apply_config(void) { mutex_lock ( &SpiLock ); raspicomm_spi0_send( SpiConfig ); raspicomm_spi0_send( 0x8600 ); // enable receive by disabling RTS (TE set so that no data is sent) mutex_unlock ( &SpiLock ); }
// called by the kernel after write() is called from userspace and write_room() returns > 0 static int raspicommDriver_write(struct tty_struct* tty, const unsigned char* buf, int count) { int bytes_written = 0; int receive; // int txdata; #if DEBUG printk(KERN_INFO "raspicomm: raspicommDriver_write(count=%i)\n", count); #endif mutex_lock(&SpiLock); // insert them into the transmit queue for (bytes_written = 0; bytes_written < count; bytes_written++) { if (queue_enqueue(&TxQueue, buf[bytes_written]) < 0) break; } // SpiConfig = SpiConfig | 0xC800; // set bit 15, 14, TM bit SpiConfig = SpiConfig | MAX3140_UART_T | MAX3140_UART_R | MAX3140_UART_TM; receive = raspicomm_spi0_send( SpiConfig ); if (receive & MAX3140_UART_T) // transmit buffer is ready to accept data { // txdata = queue_dequeue(&TxQueue); // javicient char aux = queue_dequeue(&TxQueue); raspicomm_spi0_send( 0x8000 | aux | raspicomm_max3140_get_parity_flag(aux)); // raspicomm_spi0_send( 0x8000 | txdata | raspicomm_max3140_get_parity_flag((char)txdata)); } mutex_unlock(&SpiLock); return bytes_written; }
// the bottom half of the irq handler, is allowed to get some sleep void raspicomm_irq_work_queue_handler(void *arg) { int rxdata, txdata; // lock on the transmit queue mutex_lock( &SpiLock ); // #if DEBUG // printk( KERN_INFO "raspicomm: raspicomm_irq_handler (%i)", irq); // #endif // issue a read command to discover the cause of the interrupt rxdata = raspicomm_spi0_send(0); // DEBUG: log data // #if DEBUG // printk( KERN_INFO "raspicomm: raspicomm_irq_handler rxdata=%X", rxdata); // #endif // read the data while(rxdata & MAX3140_UART_R) // while we are receiving { // handle the received data raspicomm_rs485_received( OpenTTY, rxdata & 0x00FF ); // get the next rxdata rxdata = raspicomm_spi0_send(0); } // write the data if ((rxdata & MAX3140_UART_T) && (SpiConfig & MAX3140_UART_TM)) { if (!queue_is_empty(&TxQueue)) { txdata = queue_dequeue(&TxQueue); // parity flag // raspicomm_spi0_send( MAX3140_UART_TM | txdata | raspicomm_max3140_get_parity_flag((char)txdata) ); // raspicomm_spi0_send( 0x8000| txdata ); raspicomm_spi0_send( MAX3140_UART_R | txdata ); } else { // mask transmit buffer empty interrupt SpiConfig = SpiConfig & ~0x0800; // clear the TM bit SpiConfig = SpiConfig | 0xc000; // set bits 15 and 14 raspicomm_spi0_send(SpiConfig); // usleep(SwBacksleep); udelay(SwBacksleep); // there is no usleep function in the kernel raspicomm_spi0_send(0x8600); // enable receive by disabling RTS (TE set so that no data is sent) } } // unlock the transmit queue mutex_unlock( &SpiLock ); }