Subversion Repositories svn.mios32

Rev

Rev 598 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
452 philetaylo 1
/*
2
 * MBHP_DMX512 module driver
3
 *
4
 * ==========================================================================
5
 *
6
 *  Copyright (C) 2009 Phil Taylor (phil@taylor.org.uk)
7
 *      As usual with MASSIVE help from TK!
8
 *  Licensed for personal non-commercial use only.
9
 *  All other rights reserved.
10
 *
11
 * The default configuration is currently to use the first serial port for DMX
12
 * This can be changed in dmx.h
13
 * ==========================================================================
14
 */
15
 
16
/////////////////////////////////////////////////////////////////////////////
17
// Include files
18
/////////////////////////////////////////////////////////////////////////////
19
 
20
#include <mios32.h>
21
#include <FreeRTOS.h>
22
#include <portmacro.h>
23
#include <task.h>
24
#include <queue.h>
25
#include <semphr.h>
26
#include <FreeRTOS.h>
27
#include <portmacro.h>
28
 
29
#include "dmx.h"
30
 
31
#define PRIORITY_TASK_DMX       ( tskIDLE_PRIORITY + 3 )
32
 
33
xSemaphoreHandle xDMXSemaphore;
34
 
35
/////////////////////////////////////////////////////////////////////////////
36
// Local variables
37
/////////////////////////////////////////////////////////////////////////////
38
static u8 dmx_tx_buffer[DMX_UNIVERSE_SIZE]; // Buffer for outgoing DMX universe.
39
 
40
static u16 dmx_baudrate_brr;        // This stores the contents of the BRR register for DMX sending
41
static u16 break_baudrate_brr;  // This is the BRR register when sending a break.
42
static volatile u16 dmx_current_channel;
43
static volatile u8 dmx_state;
44
 
45
static void TASK_DMX(void *pvParameters);
46
 
47
////////////////////////////////////////////////////////////////////////////
48
//! Initialize DMX Interface
49
//! \param[in] mode currently only mode 0 supported
50
//! \return < 0 if initialisation failed
51
/////////////////////////////////////////////////////////////////////////////
52
s32 DMX_Init(u32 mode)
53
{
54
 
55
  // currently only mode 0 supported
56
  if( mode != 0 )
57
    return -1; // unsupported mode
58
  // configure UART pins
59
    GPIO_InitTypeDef GPIO_InitStructure;
60
  GPIO_StructInit(&GPIO_InitStructure);
61
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
62
 
63
  // outputs as push-pull
64
  GPIO_InitStructure.GPIO_Pin = DMX_TX_PIN;
65
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
66
  GPIO_Init(DMX_TX_PORT, &GPIO_InitStructure); 
67
 
68
  // inputs with internal pull-up
69
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
70
  GPIO_InitStructure.GPIO_Pin = DMX_RX_PIN;
71
  GPIO_Init(DMX_RX_PORT, &GPIO_InitStructure);
72
 
73
  // enable USART clock
74
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
75
 
76
    // Set DMX data format and baud rate (8 bit, 2 stop bits and 250000 baud)
77
  USART_InitTypeDef USART_InitStructure;
78
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
79
  USART_InitStructure.USART_StopBits = USART_StopBits_2;
80
  USART_InitStructure.USART_Parity = USART_Parity_No;
81
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
82
  USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
83
 
84
  USART_InitStructure.USART_BaudRate = BREAK_BAUDRATE;
85
  USART_Init(DMX, &USART_InitStructure);
86
  break_baudrate_brr=DMX->BRR;  // Store the BRR value for quick changes.
87
 
88
  USART_InitStructure.USART_BaudRate = DMX_BAUDRATE;
89
  USART_Init(DMX, &USART_InitStructure);
90
  dmx_baudrate_brr=DMX->BRR;    // Store the BRR value for quick changes.
91
 
92
    // configure and enable UART interrupts
93
  NVIC_InitTypeDef NVIC_InitStructure;
94
 
95
  NVIC_InitStructure.NVIC_IRQChannel = DMX_IRQ_CHANNEL;
96
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 11; //MIOS32_IRQ_UART_PRIORITY; // defined in mios32_irq.h
97
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
98
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
99
  NVIC_Init(&NVIC_InitStructure);
100
    USART_Cmd(DMX, ENABLE);
101
    dmx_state=DMX_IDLE;
102
    dmx_current_channel=0;
103
    // Create timer to send DMX universe.
104
    vSemaphoreCreateBinary(xDMXSemaphore);
2425 tk 105
  xTaskCreate(TASK_DMX, "DMX", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_DMX, NULL);
452 philetaylo 106
    return 0;
107
}
108
 
109
/////////////////////////////////////////////////////////////////////////////
110
// This task handles sending the DMX universe
111
/////////////////////////////////////////////////////////////////////////////
112
static void TASK_DMX(void *pvParameters)
113
{
114
  portTickType xLastExecutionTime;
115
 
116
  // Initialise the xLastExecutionTime variable on task entry
117
  xLastExecutionTime = xTaskGetTickCount();
118
 
119
  while( 1 ) {
120
    vTaskDelayUntil(&xLastExecutionTime, 35 / portTICK_RATE_MS);
121
        if (dmx_state==DMX_IDLE)
122
        {
123
          if (xSemaphoreTake(xDMXSemaphore, 10)==pdTRUE) { // Stop the universe from being changed while we are sending it.
124
            // send break and MAB with slow baudrate
125
            DMX->SR &= ~USART_FLAG_TC;
126
            USART_ITConfig(DMX, USART_IT_TC, ENABLE); // enable TC interrupt - triggered when transmission of break/MAB is completed
127
            DMX->BRR=break_baudrate_brr;        // Set baudrate to 90.9K so send break/MAB
128
            dmx_state=DMX_BREAK;
598 philetaylo 129
            //DMX->DR = 0x80;                           // start transmission (MSB used for MAB)
130
            DMX->DR = 0x00;                           // start transmission (stop bits provide MAB)
452 philetaylo 131
          }
132
        }
133
  }
134
}
135
 
136
/////////////////////////////////////////////////////////////////////////////
137
// Change the value of a single channel
138
/////////////////////////////////////////////////////////////////////////////
139
s32 DMX_SetChannel(u16 channel, u8 value)
140
{
141
 
142
    if (channel<DMX_UNIVERSE_SIZE) {
143
            //if (xSemaphoreTake(xDMXSemaphore, 1)==pdTRUE)
144
            //{
145
                dmx_tx_buffer[channel]=value;
146
            //  xSemaphoreGive(xDMXSemaphore);
147
            //}
148
    }
149
    else
150
        return -1;
151
    return 0;
152
 
153
    }
154
 
155
/////////////////////////////////////////////////////////////////////////////
156
// Get the value of a single channel
157
/////////////////////////////////////////////////////////////////////////////
158
s32 DMX_GetChannel(u16 channel)
159
{
160
    if (channel<DMX_UNIVERSE_SIZE) {
161
        u32 val=(s32)dmx_tx_buffer[channel];
162
        return val;
163
    }
164
    else
165
        return -1;
166
}
167
 
168
 
169
 
170
/////////////////////////////////////////////////////////////////////////////
171
// Interrupt handler for DMX UART
172
/////////////////////////////////////////////////////////////////////////////
173
signed portBASE_TYPE x=pdFALSE;
174
DMX_IRQHANDLER_FUNC
175
{
176
  if( (dmx_state == DMX_BREAK) && (DMX->SR & USART_FLAG_TC) ) { // Transmission Complete flag
177
    // the combined break/MAB has been sent - disable TC interrupt, clear current TXE and enable TXE for next byte
178
    USART_ITConfig(DMX, USART_IT_TC, DISABLE);
179
    DMX->SR &= ~USART_FLAG_TXE;
180
    USART_ITConfig(DMX, USART_IT_TXE, ENABLE);
181
 
182
    dmx_current_channel=0;
183
    DMX->BRR=dmx_baudrate_brr;      // Set baudrate to 250K to send universe
184
    DMX->DR = 0x00; // start code
185
    dmx_state=DMX_SENDING;
186
  }
187
 
188
  if( DMX->SR & USART_FLAG_TXE ) {
189
    // send next byte
190
    if( (dmx_state==DMX_SENDING) && (dmx_current_channel < DMX_UNIVERSE_SIZE) ) {
191
      s32 c=DMX_GetChannel(dmx_current_channel);
192
      DMX->DR=c;
193
      dmx_current_channel++;
194
    } else {
195
      // all bytes have been sent
196
      dmx_state = DMX_IDLE;
197
      USART_ITConfig(DMX, USART_IT_TXE, DISABLE);
198
      MIOS32_BOARD_LED_Set(0xffffffff, ~MIOS32_BOARD_LED_Get());
199
      xSemaphoreGiveFromISR(xDMXSemaphore,&x);
200
    }
201
  }
202
}
203
 
204
 
205